Reputation: 29397
By safe I mean the fact that NodeList created by document.getElementsById('*');
is a live object. Some elements are added or removed dynamically as JS engine loops through it.
The thing I intend to do is loop over a whole DOM (this would be in a greasemonkey script, so not for normal web use, but I think it also applies there), check if a node CSS match some rules and according to that change the CSS.
This process takes some time and since the website has multiple scripts (changing images/news stories etc.) running on it, constantly adding and removing DOM nodes sooner or later there will be a case when a node will disappear right when it is processed.
And by fast I mean is it better to do it recursively:
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);
}
}
(but this will waste time on checking nodeType)
or by for
loop:
nodes = document.getElementsByTagName('*');
for (var i=0; i<nodes.length; i++) {
//do my stuff
}
(but this would have issues at the end where it will encounter fluctuating tip of NodeList)
Upvotes: 0
Views: 194
Reputation: 2662
Here is an example, feel free to give it a try. Tested it on about 170 nodes and it wasn't too slow, but it wasn't necessarily fast either:
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
Upvotes: 1
Reputation: 12936
There is a w3c Element Traversal Specification, see example at http://www.w3.org/TR/ElementTraversal/#example-3.2
Upvotes: 0
Reputation: 832
JavaScript is single-threaded. Only one function can run at a time. While you iterate over the DOM, it should be impossible to be modified.
Upvotes: 0