What's the best way to loop through a set of elements in JavaScript?

前端 未结 14 1786
清歌不尽
清歌不尽 2020-11-27 06:34

In the past and with most my current projects I tend to use a for loop like this:

var elements = document.getElementsByTagName(\'div\');
for (var i=0; i

        
相关标签:
14条回答
  • 2020-11-27 06:58

    I know this question is old -- but here's another, extremely simple solution ...

    var elements = Array.from(document.querySelectorAll("div"));
    

    Then it can be used like any, standard array.

    0 讨论(0)
  • 2020-11-27 06:59

    I prefer the for loop as it's more readable. Looping from length to 0 would be more efficient than looping from 0 to length. And using a reversed while loop is more efficient than a foor loop as you said. I don't have the link to the page with comparison results anymore but I remember that the difference varied on different browsers. For some browser the reversed while loop was twice as fast. However it makes no difference if you're looping "small" arrays. In your example case the length of elements will be "small"

    0 讨论(0)
  • 2020-11-27 07:02

    I had a very similar problem earlier with document.getElementsByClassName(). I didn't know what a nodelist was at the time.

    var elements = document.getElementsByTagName('div');
    for (var i=0; i<elements.length; i++) {
        doSomething(elements[i]);
    }
    

    My issue was that I expected that elements would be an array, but it isn't. The nodelist Document.getElementsByTagName() returns is iterable, but you can't call array.prototype methods on it.

    You can however populate an array with nodelist elements like this:

    var myElements = [];
    for (var i=0; i<myNodeList.length; i++) {                               
        var element = myNodeList[i];
        myElements.push(element);
    };
    

    After that you can feel free to call .innerHTML or .style or something on the elements of your array.

    0 讨论(0)
  • 2020-11-27 07:03

    Here's a nice form of a loop I often use. You create the iterated variable from the for statement and you don't need to check the length property, which can be expensive specially when iterating through a NodeList. However, you must be careful, you can't use it if any of the values in array could be "falsy". In practice, I only use it when iterating over an array of objects that does not contain nulls (like a NodeList). But I love its syntactic sugar.

    var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];
    
    for (var i=0, item; item = list[i]; i++) {
      // Look no need to do list[i] in the body of the loop
      console.log("Looping: index ", i, "item" + item);
    }
    

    Note that this can also be used to loop backwards (as long as your list doesn't have a ['-1'] property)

    var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];
    
    for (var i = list.length - 1, item; item = list[i]; i--) {
      console.log("Looping: index ", i, "item", item);
    }
    

    ES6 Update

    for...of gives you the name but not the index, available since ES6

    for (let item of list) {
        console.log("Looping: index ", "Sorry!!!", "item" + item);
    }
    
    0 讨论(0)
  • 2020-11-27 07:08

    Note that in some cases, you need to loop in reverse order (but then you can use i-- too).

    For example somebody wanted to use the new getElementsByClassName function to loop on elements of a given class and change this class. He found that only one out of two elements was changed (in FF3).
    That's because the function returns a live NodeList, which thus reflects the changes in the Dom tree. Walking the list in reverse order avoided this issue.

    var menus = document.getElementsByClassName("style2");
    for (var i = menus.length - 1; i >= 0; i--)
    {
      menus[i].className = "style1";
    }
    

    In increasing index progression, when we ask the index 1, FF inspects the Dom and skips the first item with style2, which is the 2nd of the original Dom, thus it returns the 3rd initial item!

    0 讨论(0)
  • 2020-11-27 07:12

    I think using the first form is probably the way to go, since it's probably by far the most common loop structure in the known universe, and since I don't believe the reverse loop saves you any time in reality (still doing an increment/decrement and a comparison on each iteration).

    Code that is recognizable and readable to others is definitely a good thing.

    0 讨论(0)
提交回复
热议问题