Javascript for循环不能正常工作?

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)

pim*_*vdb 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
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仍然被更新(即变小),但是这不要紧,因为你只迭代过程中,在开始时使用它,而不是.结果,你不会受到这种"怪癖"的影响.