用于替换文本DOM节点的Chrome扩展程序...不会

时间:2012-04-11 21:24:16

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

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

我正在制作我的第一个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();

1 个答案:

答案 0 :(得分:3)

由于您正在修改DOM,因此可能也会出现迭代问题,而nodes是一个将使用DOM更新的“实时” NodeList 变化。

不确定这是否是一个问题,因为您似乎在同一个索引上进行交换,但我不确定。您可以尝试将 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");
         }
    }
};