getElementsByClassName vs querySelectorAll

后端 未结 2 1852
花落未央
花落未央 2020-11-29 08:30

if I use

var temp = document.querySelectorAll(\".class\");
for (var i=0, max=temp.length; i         


        
2条回答
  •  情话喂你
    2020-11-29 09:30

    That's because HTMLCollection returned by getElementsByClassName is live.

    That means that if you add "class" to some element's classList, it will magically appear in temp.

    The oposite is also true: if you remove the "class" class of an element inside temp, it will no longer be there.

    Therefore, changing the classes reindexes the collection and changes its length. So the problem is that you iterate it catching its length beforehand, and without taking into account the changes of the indices.

    To avoid this problem, you can:

    • Use a non live collection. For example,

      var temp = document.querySelectorAll(".class");
      
    • Convert the live HTMLCollection to an array. For example, with one of these

      temp = [].slice.call(temp);
      temp = Array.from(temp); // EcmaScript 6
      
    • Iterate backwards. For example, see @Quentin's answer.

    • Take into account the changes of the indices. For example,

      for (var i=0; i
      while(temp.length) { 
       temp[0].className = "new_class";
      }
      

提交回复
热议问题