1

「クリーンアップ」するために作成した関数に問題があります。以下のコードを参照して、その下でどのように機能するかを説明します。

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つの入力があり、クラス'keep'はありませんが、変数iは2になり、ループは停止します(4に達し、4つの要素すべてを削除する必要があります)

どんな助けでも大歓迎です。

/* アップデート */

@pimvbと@BrettWalkerのおかげで、うまく機能する最終的なコードを以下に示します。

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;
},
4

1 に答える 1

6

この.getElementsByTagName関数は、NodeList基本的に配列ですが「ライブ」であるaを返します。これは、たとえば子を削除すると自動的に更新されることを意味します。したがって、反復すると、els.lengthが変化し、22つの子を削除したときになります(残りがあります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

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);
}

これは最後の要素から始まります。まだ更新されます(つまり、.length少なくなります)が、反復中にではなく、最初にのみ使用したため、これは問題ではありません。結果として、あなたはこの「癖」に悩まされることはありません。

于 2011-08-20T12:39:40.350 に答える