在 JavaScript 中迭代 DOM 时关闭标记事件

Closing tag events when iterating over DOM in JavaScript

本文关键字:事件 JavaScript 迭代 DOM      更新时间:2023-09-26

我正在编写一个Chrome扩展程序,将HTML页面转换为不同的格式。

如果我使用 document.getElementsByTagName("*") 并循环访问该集合,我可以看到所有标记。但是,这是一个平面表示。我需要检测开始和关闭的"事件",就像 SAX 解析器一样,以便我的翻译输出保持正确的包含/嵌套。

在 JavaScript 中执行此操作的正确方法是什么?必须手动执行此操作似乎有点尴尬。还有其他方法可以做到这一点吗?

为了说明我的意思...

   <html>
       <body>
           <h1>Header</h1>
           <div>
               <p>some text and a missing closing tag
               <p>some more text</p>
           </div>
           <p>some more dirty HTML
        </body>
    <html>

我需要按以下顺序获取事件:

    html open
    body open
    h1 open
    text
    h1 close
    div open
    p open
    text
    p close
    p open
    text
    p close
    div close
    p open
    text
    p close
    body close
    html close

我感觉在迭代过程中跟踪类似 SAX 解析器的事件取决于我。还有其他选择吗?如果没有,你能指出我任何示例代码吗?

谢谢!

只需遍历每个节点和每个节点的所有子节点。当某个级别的子项耗尽时,标记将关闭。

function parseChildren(node) {
    // if this a text node, it has no children or open/close tags
    if(node.nodeType == 3) {
        console.log("text");
        return;
    }
    console.log(node.tagName.toLowerCase() + " open");
    // parse the child nodes of this node
    for(var i = 0; i < node.childNodes.length; ++i) {
        parseChildren(node.childNodes[i]);
    }
    // all the children are used up, so this tag is done
    console.log(node.tagName.toLowerCase() + " close");
}

要遍历整个页面,只需执行parseChildren(document.documentFragment) 。 您可以将console.log语句替换为您喜欢的任何行为。

请注意,此代码报告了很多text节点,因为标记之间的空格计为文本节点。 若要避免这种情况,只需展开文本处理代码:

    if(node.nodeType == 3) {
        // if this node is all whitespace, don't report it
        if(node.data.replace(/'s/g,'') == '') { return; }
        // otherwise, report it
        console.log("text");
        return;
    }
我认为

没有工具,所以你应该写一些递归函数,在其中你会以某种方式get first childget next nodeget parent等等。