JavaScript中动态更改类名

6

我有一个简单的HTML菜单:

<ul id="menu">
    <li><a id="admin" onclick="changeActive('admin');" class="active a red">Admin</a></li>
    <li><a id="dash" onclick="changeActive('dash');" class="a black">Dash</a></li>
    <li><a id="notifs" onclick="changeActive('notifs');" class="a black">Notifs</a></li>
</ul>

这个想法是动态改变活动元素。

我的当前函数是:

function changeActive(id)
    {
      document.getElementById(id).className += "active a red";
      var c = document.querySelectorAll("ul a");
      for (i in c)
      {
        fav = c[i].attributes[0];
        if(fav.value!=id)
          {
            console.log(fav.value);
            document.getElementById(fav.value).className += "a black";
          }
      }
    }

有没有更高效的解决方案?谢谢!

1
使用jQuery的addClass和removeClass是一个不错的替代选项。 - manian
@ManivannanSadasivam,这样更有效率吗? - RobG
你对“高效”的标准是什么?更快?更少的代码? - RobG
@RobG 为了防止循环(如果可能的话)并减少代码行数。 - Arjun
6个回答

8

请注意,我去掉了+=,这样您就不会每次都添加相同的类。

function changeActive(id) {
      var c = document.querySelectorAll("ul a");
      var i;
      for (i in c) {
        c[i].className = 'a black';
      }
      //update it at last
      document.getElementById(id).className = "active a red";
}

1
这很有趣。我如何将 querySelectorAll() 函数限制在我的 ul id="menu" 中? - Arjun
1
使用 querySelectorAll('#menu a') - Hari Lamichhane

3
使用classList属性及其add方法。使用remove可以移除类。
  document.getElementById(id).classList.add("active a red");

谢谢!但是,我在控制台中得到了这个错误:提供的令牌('active a red')包含HTML空格字符,这些字符在令牌中无效。 - Arjun

3
使用导航菜单时,您想在li上设置活动状态,并将样式应用于活动li中的a。
下面的代码中,li中包含id、active类和onclick处理程序(以及a中的伪href),并附带函数在单击时从所有li中移除active类,然后将其应用于所选li。然后,.active类CSS会将a颜色设为红色。

function changeActive(option){
  var option = option;
  var li = document.getElementsByTagName("li");
  for(i=0;i<li.length;i++){
     li[i].classList.remove("active");
  }
  document.getElementById(option).classList.add("active");
}
ul{list-style:none}
a{color:black;text-decoration:none}
.active a{color:red}
<ul id="menu">
    <li class="active" onclick="changeActive('admin')" id="admin"><a  href="#">Admin</a></li>
    <li onclick="changeActive('dash')" id="dash"><a href="#">Dash</a></li>
    <li onclick="changeActive('notifs')" id="notifs"><a href="#">Notifs</a></li>
</ul>


感谢您提供完整的答案!看到在这里使用CSS解决问题很有趣! - Arjun

2
如果“高效”意味着对于浏览器需要做的工作最小化,那么以下内容可能符合要求。它没有循环,只有3行代码。
您似乎想要更改所点击元素的类并将其从具有该类的所有其他元素中删除。如果您从单击侦听器传递this,则不需要getElementById。如果使用addEventListener添加侦听器,则this将设置为该元素,因此无需传递它。
而且,如果您使用querySelector,则可以直接访问已具有特定类的元素,因此:

function changeActive(evt) {
  // Get the current "active" element
  var active = document.querySelector('.active.a.red');
  // Make it not active
  active.className = 'a black';
  // Set the clicked on element to active
  this.className = 'active a red';
}

// Add listeners when the load event occurs
window.onload = function(){
  Array.prototype.forEach.call(document.querySelectorAll('#menu a'), function(a) {
    a.addEventListener('click', changeActive,false);
    console.log(a.attributes[1].value)
  });
};
.active {
  color: red;
}
<ul id="menu">
    <li><a id="admin" class="active a red">Admin</a></li>
    <li><a id="dash" class="a black">Dash</a></li>
    <li><a id="notifs" class="a black">Notifs</a></li>
</ul>

我认为在不确定你会得到什么的宿主对象上使用for..in是不明智的。也不应该假设第一个属性就是id。如果你想要id,直接使用id属性获取。


1
请检查下面的代码,HTML:
<ul id="menu">
    <li><a class="active a red">Admin</a></li>
    <li><a class="a black">Dash</a></li>
    <li><a class="a black">Notifs</a></li>
</ul>

jQuery:

$( document ).ready(function() {
    $('#menu li a').on('click', function() {
        $('#menu li a').removeClass().addClass( "a black" );
        $(this).removeClass().addClass( "active a red" );
    });
});

简化的HTML代码、简化的JS代码,没有循环,没有元素的ID引用,易于理解。 jQuery元素引用与CSS相同。

注意:请不要忘记添加jQuery库。


0
 document.getElementById(id).setAttribute("class", "class-name");

4
请提供进一步的细节以扩展您的答案,例如工作代码或文档引用。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接