我遇到的问题是我写的“清理”,看下面的代码,我会解释它是如何工作的。
clean: function (e) {
var
els = null,
i = 0;
if (e === undefined) {
e = this.cont;
}
els = e.getElementsByTagName('*');
for (i=0;i<els.length;i++) {
if (els[i].className.search('keep') === -1) {
e.removeChild(els[i]);
}
}
return this;
},
参数e是一个dom元素,如果没有提供this.cont也是早期存储在整个函数中的dom元素,e默认为它。
该函数循环遍历所有子元素并检查它没有类保持(相当明显的是这样做)并删除任何不匹配的元素。
这一切似乎都有效但我有一个元素有2个图像和2个输入没有类'保持'但变量我只到2并且循环停止(它应该达到4并删除所有四个元素)
任何帮助将不胜感激。
/ * UPDATE * /
感谢@pimvb和@Brett Walker,最终的代码很有效。
clean: function (e) {
var
els = null,
i = 0;
if (e === undefined) {
e = this.cont;
}
els = e.getElementsByTagName('*');
i = els.length;
while (i--) {
if (els[i].className.search('keep') === -1) {
els[i].parentNode.removeChild(els[i]);
}
}
return this;
},
答案 0 :(得分:6)
.getElementsByTagName
函数返回一个NodeList
,它基本上是一个数组但是“实时”,这意味着它会自动更新,例如:删除一个孩子。因此,在进行迭代时,els.length
正在发生变化,当您删除2个子项时(剩下2
),结果为4 - 2 = 2
。移除了2个孩子时i == 2
,所以循环会过早地结束你的期望。
为了避免这种情况并使其成为“静态”数组,您可以将其转换为这样的数组,不更新自身:
els = [].slice.call(e.getElementsByTagName('*')); // [].slice.call is a trick to
// convert something like a NodeList
// into a static, real array
正如布雷特沃克指出的那样,你也可以向后迭代,如下:
http://jsfiddle.net/pimvdb/cYKxU/1/
var elements = document.getElementsByTagName("a"),
i = elements.length;
while(i--) { // this will stop as soon as i == 0 because 0 is treated as false
var elem = elements[i]; // current element
if(elem.className == "test") // remove if it should be removed
elem.parentNode.removeChild(elem);
}
这将从最后一个元素开始。 .length
仍然会更新(即变得更少),但这并不重要,因为您只在开始时使用它,而不是在迭代期间使用它。因此,您不会受到这种'怪癖'的困扰。