2012-01-04 13 views
0

安全なことは、document.getElementsById('*');によって作成されたNodeListが実際のオブジェクトであるということです。いくつかの要素は、JSエンジンがそれをループするときに動的に追加または削除されます。純粋なJSでDOM全体をループする最も速く、安全で正しい方法は何ですか?

DOM全体(これはgreasemonkeyスクリプトにありますので、通常のウェブ用ではありませんが、それもそこに当てはまると思います)にループすることです。その変更によると、CSS。

このプロセスには時間がかかっています。ウェブサイトには複数のスクリプト(画像やニュースなどの変更)が実行されているため、DOMノードをいつでも追加したり削除したりすることができます。処理されます。

と高速で、私が意味する、それは再帰的にそれを行うには良いです:

function traverseDOM(node,f) { 
    if (node.nodeType !== 1) return; 
    f.apply(node); 
    for (var i = 0; i < node.childNodes.length; i++) { 
    traverseDOM(node.childNodes[i],f); 
    } 
} 

(これはnodeTypeプロパティをチェックするには時間を無駄にします) またはforループによって:

nodes = document.getElementsByTagName('*'); 
for (var i=0; i<nodes.length; i++) { 
    //do my stuff 
} 

(しかし、この最後にノードリストの先端に遭遇する問題があります)

答えて

0

JavaScriptはシングルスレッドです。一度に実行できる関数は1つだけです。 DOMを反復処理する間は、変更することは不可能です。

1

での例を参照してくださいは一例であり、それを試してみること自由に感じ。約170のノードでテストしたが、それほど遅くはなかったが、必ずしも高速ではなかった。

function walk (node, func) { 
    func(node); 
    node = node.childNodes[0]; 

    while (node) { 
     walk(node, func); 
     node = node.nextSibling; 
    } 
} 

var doc = document; //save a reference to the document (might be a tiny bit faster... not sure) 
var bd = doc.body; //start to walk the DOM from the body 
var o = doc.getElementById('some_div'); //some div to output to 
var arr = []; //array to collect all nodes 

walk(bd, function(n){ 
    if (n.nodeType === 1) { 
     n.style.border = "2px solid red"; //change the border color for each node that was found 
     o.innerHTML += "<pre>" + n.nodeName + "</pre>"; //output each node's name to a div 
     arr.push(n); //add each node to the array 
    } 
}); 

console.log(arr.length); //log the total number of nodes affected 
関連する問題