2017-06-02 2 views
0

Wenn ich eine durch querySelectorAll abgerufene Nodelist durchlaufen und eine neue Klasse für jede hinzufügen, dauert es viel weniger Zeit (3ms) als die von getElementsByClassName (100ms) .Warum?querySelectorAll vs getElementsByClassName

var container = document.getElementById('box-container'); 
var button = document.getElementById('button'); 

for (var i = 0; i < 3000; i++) { 
    var div = document.createElement('div'); 
    div.classList.add('box'); 
    div.index = i; 
    container.appendChild(div); 
} 

button.addEventListener('click', function() { 

    var box1 = container.getElementsByClassName('box'); 
    for (var i = 1;i < box1.length; i+=2){ 
     box1[i].classList.toggle('gray'); 
    }; 

    var box2 = container.querySelectorAll('.box'); 
    for (var i = 1;i < box2.length; i+=2){ 
     box2[i-1].classList.toggle('gray'); 
    }; 

}); 

Antwort

0

Der Unterschied ist der Typ der Liste, auf der Sie laufen.
box1 ist eine NodeList (a.k.a eine Live-Node-Liste), die aktualisiert wird, wenn sich das DOM ändert. box2 ist ein Array, das eine non-live Liste ist - also ändert sich das Ändern des DOM nicht. Was passiert, wenn Sie auf box1 iterieren, ist, dass bei jeder Klassenumschaltung die box1 Liste aktualisiert wird, was den Overhead verursacht. Hier ist ein Test, den Sie leicht ausführen können:

var container = document.getElementById('box-container'); 
var button = document.getElementById('button'); 

for (var i = 0; i < 6000; i++) { // added 3000 more to challenge modern browsers... 
    var div = document.createElement('div'); 
    div.classList.add('box'); 
    div.index = i; 
    container.appendChild(div); 
} 

button.addEventListener('click', function() { 

    var box1 = container.getElementsByClassName('box'); 
    for (var i = 1; i < box1.length; i += 2) { 
     box1[i].classList.toggle('gray'); 
    } 

    var deadBox1 = []; 
    for (i = 0; i < box1.length; i++) { 
     deadBox1[i] = box1[i]; 
    } 

    for (var i = 1; i < deadBox1.length; i += 2) { 
     deadBox1[i].classList.toggle('gray'); 
    } 

    var box2 = container.querySelectorAll('.box'); 
    for (i = 1; i < box2.length; i += 2) { 
     box2[i - 1].classList.toggle('gray'); 
    } 

}); 

nun das Chrom Leistung (oder Timeline) Tool. Sie können den Unterschied hier sehen: See the diff between the <code>box1</code> and the <code>deadBox1</code> toggle loops performance

Verwandte Themen