遍历所有 html 标签,包括 Javascript 中的子标签

Iterate through all html tags, including children in Javascript

只是为了阐明我正在尝试做的事情,我正在尝试制作一个 Chrome 扩展,它可以循环遍历当前页面的 HTML 并删除 html包含特定文本的标签。但是我在遍历 every html 标签时遇到了问题。

我搜索了很多 answer and pretty much every answer 说要使用:

var items = document.getElementsByTagName("*");
 for (var i = 0; i < items.length; i++) {
     //do stuff
 }

但是,我注意到如果我使用 "items," 中的元素从页面重建 HTML,我得到的东西与页面的实际 HTML 不同。

例如下面的代码returns false:

var html = "";
var elems = document.getElementsByTagName("*");
for (var i = 0; i < elems.length; i++) {
  html += elems[i].outerHTML;
}

alert(document.body.outerHTML == html)
我还注意到上面的代码并没有给出所有的 html 标签,而是将它们分组为一个标签,例如:

var html = "";
var elems = document.getElementsByTagName("*");
alert(elems[0].outerHTML);
我尝试通过递归查找元素的子元素来修复上述问题,但我似乎无法让它工作。

理想情况下,我希望能够获取每个单独的标签,而不是包含在其他标签中的标签。我是 Javascript 的新手,所以任何 advice/explanations 或示例代码(如果可能,在纯 javascript 中)关于我做错了什么都会非常有帮助。我也意识到我的方法可能是完全错误的,所以欢迎任何更好的想法。

JavaScript中对DOM元素的引用是对实际节点内存地址的引用,所以你可以这样做(见working jsfiddle):

Array.prototype.slice.call(document.getElementsByTagName('*')).forEach(function(node) {
    if(node.innerHTML === 'Hello') {
        node.parentNode.removeChild(node);
    }
});

显然 node.innerHTML === 'Hello' 只是一个示例,因此您可能想弄清楚您希望如何匹配文本内容(也许使用正则表达式?)

你需要的是著名的 Douglas Crockford WalkTheDOM:

function walkTheDOM(node, func)
{
  func(node);
  node = node.firstChild;
  while (node)
  {
    walkTheDOM(node, func);
    node = node.nextSibling;
  }
}

对于每个节点,func 将被执行。您可以通过注入适当的功能来过滤、转换或其他任何东西。

要删除包含特定文本的节点,您可以执行以下操作:

function removeAll(node)
{
    // protect against "node === undefined"
    if (node && node.nodeType === 3) // TEXT_NODE
    {
        if (node.textContent.indexOf(filter) !== -1) // contains offending text
        {
            node.parentNode.removeChild(node);
        }
    }
}

你可以这样使用它:

filter = "the offending text";
walkTheDOM(document.getElementsByTagName("BODY")[0], removeAll);

如果您想通过冒犯文本进行参数化,您也可以通过将 removeAll 转换为实例化的闭包来实现。