Dav*_*osh 1 javascript dom loops getelementsbytagname
我遇到了一个我写的"清理"功能的问题,请看下面的代码,我将解释它是如何工作的.
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;
},
Run Code Online (Sandbox Code Playgroud)
参数e是一个dom元素,如果没有提供this.cont也是一个早期存储在整个函数中的dom元素,e默认为它.
该函数循环遍历所有子元素并检查它没有类保持(相当明显的是这样做)并删除任何不匹配的元素.
这一切似乎都工作但我有一个元素有2个图像和2个输入没有类'保持'但变量我只到2并且循环停止(它应该达到4并删除所有四个元素)
任何帮助将不胜感激.
/*更新*/
感谢@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;
},
Run Code Online (Sandbox Code Playgroud)
该.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
Run Code Online (Sandbox Code Playgroud)
正如Brett Walker指出的那样,你也可以向后迭代,如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
这将从最后一个元素开始.将.length仍然被更新(即变小),但是这不要紧,因为你只迭代过程中,在开始时使用它,而不是.结果,你不会受到这种"怪癖"的影响.