4

クラス名fooのドキュメント内のすべての要素を検索し、それらをすべて削除する次のコードがあります。

        function(doc) {
            var items = doc.getElementsByClassName('foo');
            alert(items.length);
            if(items.length>0) {
                for(var i=0;i<items.length;i++) {
                    alert(i);
                    doc.body.removeChild(items[i]);
                }
        }

たとえば、items.lengthは3で、関数は1つのループを実行した後に終了し、長さが8の場合は3で終了します。助けていただければ幸いです。また、関数を何度も実行すると、最終的にすべての要素が削除されます。

4

2 に答える 2

11

あなたの問題は、NodeList返送されたものgetElementsByClassName()がライブであるということです。Felixが提案するように、最初に配列に変換するか、逆方向に繰り返します。

var items = doc.getElementsByClassName('foo');
var i = items.length;
while (i--) {
    items[i].parentNode.removeChild(items[i]);
}

これが機能するのは、反復ごとにリストから削除されるアイテムがリストの最後のアイテムであり、したがって以前のアイテムには影響しないためです。

また、要素の直接の子ではない要素を処理する必要がある場合に備えて、より一般化するためにに変更doc.bodyしました。items[i].parentNode<body>

于 2012-06-21T23:09:45.107 に答える
9

問題はitemsライブ NodeListであるということです。つまり、リスト()のプロパティにアクセスするたびitems.lengthに、リストが再評価されます(要素が再度検索されます)。
その間に要素を削除するため、リストは短くなりますが、インデックスは保持されます。

NodeList最初にを配列に変換できます。

var items = [].slice.call(doc.getElementsByClassName('foo'));

DOM要素を削除しても、配列サイズは変更されません。

于 2012-06-21T23:09:00.143 に答える