【问题标题】:Chrome extension to replace text DOM nodes... doesn't用于替换文本 DOM 节点的 Chrome 扩展...不
【发布时间】:2012-04-24 05:54:49
【问题描述】:

更新:在“我不是”的指导下,我解决了这个问题;最后的工作代码。

我目前正在开发我的第一个 Chrome 扩展程序,旨在对查看的网页执行文本替换。我一直在努力尝试了解 DOM 操作,最终我想出了以下内容。理论上这应该遍历整个 DOM 表,找到文本节点,克隆它们,替换文本(如果适用),并用克隆替换原始节点。

这是我的 manifest.json...

{
    "name": "My app",
    "version": "1.0",
    "manifest_version": 2,
    "description": "Do thing.",
    "permissions": [
        "tabs", "http://*/"
    ],
    "content_scripts": [
        {
            "matches": ["http://*/*"],
            "js": ["myapp.js"],
            "run_at": "document_end"
        }
    ]
}

还有 myapp.js;

function myapp() {
    var nodes = document.getElementsByTagName("*");
        for(var i = 0; i < nodes.length; i++) {
             if(nodes[i].type == "text") {
                  var parent = nodes[i].parentnode;
                  var newnode = nodes[i].cloneNode(true);
                  newnode.data.replace("test text","replacement test text");
                  parent.replaceChild(newnode, nodes[i]);
             };
        };
};
myapp();

我已导入并激活了扩展程序。 Chrome 的 javascript 控制台之前已显示错误,这意味着它正在运行,但现在没有,这意味着没有基本的拼写错误。我认为要么我对如何更改或交换文本节点有误,要么对如何设置清单文件或 js 文件有基本的误解,但我试图找出哪个我碰壁了。

任何帮助将不胜感激!

更新:这是工作版本。

function myapp() {
    var nodes = document.getElementsByTagName("*");
    for(var i = 0; i < nodes.length; i++) {
         var subNodes = nodes[i].childNodes;
         for (var j = 0; j < subNodes.length; j++) {
            var node = subNodes[j];
            if (node.nodeType === 3) {
                if (node.data) {
                    node.data = node.data.replace(/test text/g,"replacement test text");
                }
            }
        }
    }
};
myapp();

【问题讨论】:

    标签: javascript dom google-chrome google-chrome-extension


    【解决方案1】:

    可能也存在迭代问题,因为您正在修改 DOM,nodes 是一个“实时”NodeList,它将随着 DOM 更改而更新。

    不确定这是否是一个问题,因为您似乎在同一索引处进行交换,但我不确定。您可以尝试将 NodeList 转换为数组,或尝试反向迭代。


    但由于您只处理文本节点,因此您似乎根本不需要.replaceChild。您可以直接更新文本节点的.data


    另一件事是您正在检查 .type 属性,而它应该是 .nodeType 属性...

    if(nodes[i].nodeType == 3) {
    

    或者nodeName...

    if(nodes[i].nodeName == '#text') {
    

    哦,还有一件事。您无法使用getElementsByTagName('*') 获取文本节点,因为它只获取元素

    如果您决定这样做,则需要添加代码来处理元素的子文本节点。

    function myapp() {
        var nodes = document.getElementsByTagName("*");
        for(var i = 0; i < nodes.length; i++) {
             var el = nodes[i];
             for (var j = 0; j < el.childNodes; j++) {
                 var node = el.childNodes[j];
                 if (node.nodeType === 3)
                     node.data = node.data.replace("test text","replacement test text");
             }
        }
    };
    

    【讨论】:

    • 天哪,有很多值得研究的地方!感谢所有提示:)
    • @aawood:我刚刚添加了更多内容。您没有获取任何文本节点,只是获取元素。我将提供另一个可能的解决方案的更新。
    • 知道了!感谢您的所有帮助,我不敢想如果没有您的领导需要多长时间。我会用解决方案更新描述。
    • @aawood:不客气,尽管我认为您可能已经从工作版本中删除了一行。我没有看到分配给 subNodes 的任何集合。
    • 呸,是的,完全正确!这就是我在将代码添加到帖子时稍微更改代码的结果!我现在就修:)
    猜你喜欢
    • 1970-01-01
    • 2010-12-02
    • 2018-03-25
    • 2022-01-21
    • 2018-05-21
    • 1970-01-01
    • 2011-08-13
    • 2018-02-28
    • 1970-01-01
    相关资源
    最近更新 更多