我试图在一个页面上循环所有元素,所以我想检查存在于这个页面上的一个特殊类的每个元素。

我怎么说我要检查每个元素呢?


当前回答

使用var all = document.getElementsByTagName("*")获取所有元素;For (var i=0, max=all.length;I < max;我+ +);如果需要检查每个元素,则可以,但会导致检查或循环重复元素或文本。

下面是一个递归实现,只检查或循环所有DOM元素的每个元素一次,并追加:

(感谢@George Reith的递归答案:将HTML映射到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);

}

其他回答

使用*

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

安迪e给出了一个很好的回答。

我会补充,如果你觉得选择所有的子在一些特殊的选择器(这需要发生在我最近),你可以应用方法“getElementsByTagName()”对任何DOM对象你想要。

举个例子,我需要解析网页的“视觉”部分,所以我做了这个

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

这绝对不会考虑到头部部分。

最好的解决方案是使用递归:

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]);
        }
    }
}

与其他建议不同的是,这个解决方案不需要为所有节点创建一个数组,因此内存占用更少。更重要的是,它能发现更多的结果。我不确定这些结果是什么,但在chrome上测试时,它发现比document.getElementsByTagName("*")多50%的节点;

你可以传递一个*给getElementsByTagName(),这样它就会返回页面中的所有元素:

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

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

请注意,您可以使用querySelectorAll(),如果它可用(IE9+, IE8中的CSS),只查找具有特定类的元素。

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

这无疑会加快现代浏览器的速度。


浏览器现在支持NodeList上的foreach。这意味着您可以直接循环元素,而不必编写自己的for循环。

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

性能注意事项-通过使用特定的选择器,尽最大努力确定您正在寻找的范围。通用选择器可以根据页面的复杂程度返回大量节点。另外,考虑使用document.body. queryselectorall而不是document。当你不关心<head> children. querySelectorAll。

使用var all = document.getElementsByTagName("*")获取所有元素;For (var i=0, max=all.length;I < max;我+ +);如果需要检查每个元素,则可以,但会导致检查或循环重复元素或文本。

下面是一个递归实现,只检查或循环所有DOM元素的每个元素一次,并追加:

(感谢@George Reith的递归答案:将HTML映射到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);

}