当我遍历querySelectorAll获取的节点列表并为每个节点列表添加一个新类时,它花费的时间(3ms)比getElementsByClassName(100ms)获得的时间少得多。为什么?
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');
};
});
答案 0 :(得分:2)
区别在于您正在运行的列表类型
box1
是NodeList(a.k.a是一个活动节点列表),它在DOM更改时更新。 box2
是一个数组,它是一个non-live
列表 - 因此更改DOM不会影响它。
迭代box1
时会发生的情况是,在每个类切换时,box1
列表都会更新,从而导致开销。
这是一个你可以轻松运行的测试:
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');
}
});