Javascript 在纯JS中循环整个DOM最快速、安全和正确的方法是什么?

Javascript 在纯JS中循环整个DOM最快速、安全和正确的方法是什么?,javascript,loops,nodelist,Javascript,Loops,Nodelist,safe是指由document.getElementsById('*')创建的节点列表是一个活动对象。当JS引擎在其中循环时,会动态添加或删除某些元素 我打算做的事情是在整个DOM上循环(这将是一个greasemonkey脚本,因此不适用于正常的web使用,但我认为它也适用于那里),检查节点CSS是否匹配一些规则,并根据这些规则更改CSS 这个过程需要一些时间,因为网站上有多个脚本(更改图像/新闻故事等)在运行,所以不断添加和删除DOM节点迟早会出现这样的情况,即节点在处理时立即消失 我所说的快

safe是指由
document.getElementsById('*')创建的节点列表是一个活动对象。当JS引擎在其中循环时,会动态添加或删除某些元素

我打算做的事情是在整个DOM上循环(这将是一个greasemonkey脚本,因此不适用于正常的web使用,但我认为它也适用于那里),检查节点CSS是否匹配一些规则,并根据这些规则更改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);
  }
}

(但在最后会遇到节点列表的波动提示)JavaScript是单线程的。一次只能运行一个函数。当您在DOM上迭代时,应该不可能对其进行修改。

有一个w3c元素遍历规范,请参见

中的示例这里是一个示例,可以尝试一下。在大约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
函数漫游(节点,函数){
func(节点);
node=node.childNodes[0];
while(节点){
walk(节点,func);
node=node.nextSibling;
}
}
var doc=单据//保存对文档的引用(可能快一点…不确定)
var bd=doc.body//从主体开始遍历DOM
var o=doc.getElementById('some_div')//要输出到的某些div
var-arr=[]//数组以收集所有节点
步行(bd,功能(n){
if(n.nodeType==1){
n、 style.border=“2px纯红”;//更改找到的每个节点的边框颜色
o、 innerHTML+=“”+n.nodeName+“”;//将每个节点的名称输出到一个div
arr.push(n);//将每个节点添加到数组中
}
});
控制台日志(arr.length)//记录受影响的节点总数
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