简体   繁体   English

Javascript:如何遍历页面上的所有 DOM 元素?

[英]Javascript: How to loop through ALL DOM elements on a page?

I'm trying to loop over ALL elements on a page, so I want to check every element that exists on this page for a special class.我正在尝试遍历页面上的所有元素,因此我想检查此页面上存在的每个元素是否有一个特殊的类。

So, how do I say that I want to check EVERY element?那么,我怎么说我想检查每个元素?

You can pass a * to getElementsByTagName() so that it will return all elements in a page:您可以将*传递给getElementsByTagName()以便它返回页面中的所有元素:

var all = document.getElementsByTagName("*");

for (var i=0, max=all.length; i < max; i++) {
     // Do something with the element here
}

Note that you could use querySelectorAll() , if it's available (IE9+, CSS in IE8), to just find elements with a particular class.请注意,如果可用(IE9+,IE8 中的 CSS querySelectorAll() ,您可以使用querySelectorAll()来查找具有特定类的元素。

if (document.querySelectorAll)
    var clsElements = document.querySelectorAll(".mySpeshalClass");
else
    // loop through all elements instead

This would certainly speed up matters for modern browsers.这肯定会加快现代浏览器的处理速度。


Browsers now support foreach on NodeList .浏览器现在支持NodeList 上的 foreach This means you can directly loop the elements instead of writing your own for loop.这意味着您可以直接循环元素而不是编写自己的 for 循环。

document.querySelectorAll('*').forEach(function(node) {
    // Do whatever you want with the node object.
});

Performance note - Do your best to scope what you're looking for by using a specific selector.性能说明- 尽最大努力使用特定选择器来确定您正在寻找的范围。 A universal selector can return lots of nodes depending on the complexity of the page.根据页面的复杂性,通用选择器可以返回大量节点。 Also, consider using document.body.querySelectorAll instead of document.querySelectorAll when you don't care about <head> children.另外,当您不关心<head>子项时,请考虑使用document.body.querySelectorAll而不是document.querySelectorAll

Was looking for same.正在寻找相同的。 Well, not exactly.嗯,不完全是。 I only wanted to list all DOM Nodes.我只想列出所有 DOM 节点。

var currentNode,
    ni = document.createNodeIterator(document.documentElement, NodeFilter.SHOW_ELEMENT);

while(currentNode = ni.nextNode()) {
    console.log(currentNode.nodeName);
}

To get elements with a specific class, we can use filter function.要获取具有特定类的元素,我们可以使用过滤器功能。

var currentNode,
    ni = document.createNodeIterator(
                     document.documentElement, 
                     NodeFilter.SHOW_ELEMENT,
                     function(node){
                         return node.classList.contains('toggleable') ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
                     }
         );

while(currentNode = ni.nextNode()) {
    console.log(currentNode.nodeName);
}

Found solution on MDNMDN上找到解决方案

As always the best solution is to use recursion:与往常一样,最好的解决方案是使用递归:

loop(document);
function loop(node){
    // do some thing with the node here
    var nodes = node.childNodes;
    for (var i = 0; i <nodes.length; i++){
        if(!nodes[i]){
            continue;
        }

        if(nodes[i].childNodes.length > 0){
            loop(nodes[i]);
        }
    }
}

Unlike other suggestions, this solution does not require you to create an array for all the nodes, so its more light on the memory.与其他建议不同的是,此解决方案不需要您为所有节点创建一个数组,因此它对内存的了解更多。 More importantly, it finds more results.更重要的是,它找到了更多的结果。 I am not sure what those results are, but when testing on chrome it finds about 50% more nodes compared to document.getElementsByTagName("*");我不确定这些结果是什么,但是在 chrome 上进行测试时,它发现与document.getElementsByTagName("*");相比,节点多出约 50% document.getElementsByTagName("*");

Here is another example on how you can loop through a document or an element:这是关于如何循环遍历文档或元素的另一个示例:

function getNodeList(elem){
var l=new Array(elem),c=1,ret=new Array();
//This first loop will loop until the count var is stable//
for(var r=0;r<c;r++){
    //This loop will loop thru the child element list//
    for(var z=0;z<l[r].childNodes.length;z++){

         //Push the element to the return array.
        ret.push(l[r].childNodes[z]);

        if(l[r].childNodes[z].childNodes[0]){
            l.push(l[r].childNodes[z]);c++;
        }//IF           
    }//FOR
}//FOR
return ret;
}

对于那些使用 Jquery 的人

$("*").each(function(i,e){console.log(i+' '+e)});

Andy E. gave a good answer. Andy E. 给出了很好的答案。

I would add, if you feel to select all the childs in some special selector (this need happened to me recently), you can apply the method "getElementsByTagName()" on any DOM object you want.我想补充一点,如果您想选择某个特殊选择器中的所有孩子(最近我遇到了这种情况),您可以在您想要的任何 DOM 对象上应用“getElementsByTagName()”方法。

For an example, I needed to just parse "visual" part of the web page, so I just made this例如,我只需要解析网页的“视觉”部分,所以我做了这个

var visualDomElts = document.body.getElementsByTagName('*');

This will never take in consideration the head part.这永远不会考虑头部。

from this link从这个链接
javascript reference JavaScript 参考

<html>
<head>
<title>A Simple Page</title>
<script language="JavaScript">
<!--
function findhead1()
{
    var tag, tags;
    // or you can use var allElem=document.all; and loop on it
    tags = "The tags in the page are:"
    for(i = 0; i < document.all.length; i++)
    {
        tag = document.all(i).tagName;
        tags = tags + "\r" + tag;
    }
    document.write(tags);
}

//  -->
</script>
</head>
<body onload="findhead1()">
<h1>Heading One</h1>
</body>
</html>

UPDATE:EDIT更新:编辑

since my last answer i found better simpler solution自从我上次回答以来,我找到了更好的更简单的解决方案

function search(tableEvent)
    {
        clearResults()

        document.getElementById('loading').style.display = 'block';

        var params = 'formAction=SearchStocks';

        var elemArray = document.mainForm.elements;
        for (var i = 0; i < elemArray.length;i++)
        {
            var element = elemArray[i];

            var elementName= element.name;
            if(elementName=='formAction')
                continue;
            params += '&' + elementName+'='+ encodeURIComponent(element.value);

        }

        params += '&tableEvent=' + tableEvent;


        createXmlHttpObject();

        sendRequestPost(http_request,'Controller',false,params);

        prepareUpdateTableContents();//function js to handle the response out of scope for this question

    }

Use *使用*

var allElem = document.getElementsByTagName("*");
for (var i = 0; i < allElem.length; i++) {
    // Do something with all element here
}

我觉得这真的很快

document.querySelectorAll('body,body *').forEach(function(e) {

Getting all elements using var all = document.getElementsByTagName("*"); for (var i=0, max=all.length; i < max; i++);使用var all = document.getElementsByTagName("*"); for (var i=0, max=all.length; i < max; i++);获取所有元素var all = document.getElementsByTagName("*"); for (var i=0, max=all.length; i < max; i++); var all = document.getElementsByTagName("*"); for (var i=0, max=all.length; i < max; i++); is ok if you need to check every element but will result in checking or looping repeating elements or text.如果您需要检查每个元素,但会导致检查或循环重复元素或文本,这是可以的。

Below is a recursion implementation that checks or loop each element of all DOM elements only once and append:下面是一个递归实现,它只检查或循环所有 DOM 元素的每个元素一次并附加:

(Credits to @George Reith for his recursion answer here: Map HTML to JSON ) (感谢@George Reith 的递归答案: Map HTML to JSON

function mapDOMCheck(html_string, json) {
  treeObject = {}

  dom = new jsdom.JSDOM(html_string) // use jsdom because DOMParser does not provide client-side Window for element access
  document = dom.window.document
  element = document.querySelector('html')

  // Recurse and loop through DOM elements only once
  function treeHTML(element, object) {
    var nodeList = element.childNodes;

    if (nodeList != null) {
      if (nodeList.length) {
        object[element.nodeName] = []; // IMPT: empty [] array for parent node to push non-text recursivable elements (see below)

        for (var i = 0; i < nodeList.length; i++) {
          console.log("nodeName", nodeList[i].nodeName);

          if (nodeList[i].nodeType == 3) { // if child node is **final base-case** text node
            console.log("nodeValue", nodeList[i].nodeValue);
          } else { // else
            object[element.nodeName].push({}); // push {} into empty [] array where {} for recursivable elements
            treeHTML(nodeList[i], object[element.nodeName][object[element.nodeName].length - 1]);
          }
        }
      }
    }
  }

  treeHTML(element, treeObject);

}

您可以尝试使用document.getElementsByClassName('special_class');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM