【问题标题】:Replace text in website with Chrome content script extension用 Chrome 内容脚本扩展替换网站中的文本
【发布时间】:2011-08-13 10:47:59
【问题描述】:

我想创建 Google Chrome 扩展程序。它的工作是在所有网站上用另一个词替换一个词。

我有以下 manifest.json 文件:

{
  "name": "My extension",
  "version": "1.0",
  "background_page": "background.html",
  "permissions": [
    "tabs", "http://*/*"
  ],
  "content_scripts": [
    {
      "matches": ["http://*/*"],
      "js": ["myscript.js"],
      "run_at": "document_end"
    }
  ]
}

myscript.js 中的 javascript 是:

< script type="text/javascript" >
    document.body.innerHTML = document.body.innerHTML.replace("uno", "dos");
< /script >

但是这不起作用..我找不到调试内容脚本的方法,只有 background.html

【问题讨论】:

  • 根据 google 的内容安全策略 java-script 应该在单独的 js 文件中。因此,脚本标签是无关紧要的,因为您正在使用 java-script 文件,并且仅当您在 html 文件中编写脚本时才需要。在您的情况下,您只会使用标签将 js 文件包含到您的 html 中,使用 src 属性。
  • 为什么不给js的相对路径工作?例如src/inject/myscript.js

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


【解决方案1】:

使用 DOM 并修改相应 Text 节点的 data。例如

document.body.querySelector(".number").firstChild.data = "dos";

【讨论】:

  • 试图找出替换数字而不是文本,这种方法是否有效,我可以找到并替换邮政编码号码
【解决方案2】:

在这种规模的 DOM 中替换/更改文本不应该使用生硬的 HTML 正则表达式替换来完成,这是非常不安全的。您可能会在此过程中破坏 HTML。

您需要做的是遍历文档中的每个 TextNode (Node),修改其中的文本。

您的代码最终将如下所示:

var replaceTextInNode = function(parentNode){
    for(var i = parentNode.childNodes.length-1; i >= 0; i--){
        var node = parentNode.childNodes[i];

        //  Make sure this is a text node

        if(node.nodeType == Element.TEXT_NODE){
            node.textContent = /* modify text here */
        } else if(node.nodeType == Element.ELEMENT_NODE){
            //  Check this node's child nodes for text nodes to act on

            replaceTextInNode(node);
        }
    }
};

replaceTextInNode(document.body);

【讨论】:

  • 干杯,这段代码有效,但是当我查看启用此功能的 Facebook 时,它会显示所有隐藏字段(用于开发..)..
  • 是的,这就是重新加载整个 body 标签的 DOM 的棘手问题。您最好迭代 DOM 的元素并一一替换其中的文本。如果你愿意,我可以给你举个例子。
  • 如果可以的话,那将非常有帮助。
  • 启用我的 chrome 扩展后,我遇到了同样的问题。在某些网页中无法完全加载。某些按钮无法单击。即使我无法通过按谷歌帐户按钮登录 stackoverflow。有什么办法解决???请...
  • @PankajVavadiya 使用示例更新了代码。请同时点击提供的链接。
【解决方案3】:

我实际上是用 jQuery 写的:(确保你有正确的包含标签)

var replaced = $("body").html().replace(/text/g,'replace');
$("body").html(replaced);

【讨论】:

【解决方案4】:

我从 JavaNut13 和 Matt Curtis 中获取了示例,为 Reddit 创建了一个别名隐藏扩展,并为新清单 2 更新了它。它在 Reddit 上查找名为“user1”的用户并将其替换为“nobody”。根据需要进行修改。

ma​​nifest.json

{
  "name": "No Alias",
  "version": "0.1",
  "permissions": [
    "https://www.reddit.com/*"
  ],
  "content_scripts": [
    {
      "matches": ["https://www.reddit.com/*"],
      "js": ["myscript.js"],
      "run_at": "document_end"
    }
  ],
  "manifest_version": 2
}

myscript.js

document.body.innerHTML = document.body.innerHTML.replace(new RegExp("user1", "g"), "nobody");

【讨论】:

  • 这工作正常但有一个大问题是某些按钮的点击事件不能被触发。例如:启用此扩展程序后,我无法登录 gmail。我可以输入电子邮件 ID 并按提交按钮,然后它会清除文本框。任何人都可以帮助解决这个问题。
  • 动态换词怎么样?
  • 试图找出替换数字而不是文本这种方法是否有效我可以找到并替换邮政编码数字有人可以添加一个示例并添加占位符(number_here)(replace_number here)
【解决方案5】:
var matchText = function(node, regex, callback, excludeElements) { 

    excludeElements || (excludeElements = ['script', 'style', 'iframe', 'canvas', 'a']);
    console.log("Node name " + node.nodeName);
    var child = node.firstChild;

    while (child) 
    {
        switch (child.nodeType) 
        {
        case 1:
            if (excludeElements.indexOf(child.tagName.toLowerCase()) > -1)
                break;
            matchText(child, regex, callback, excludeElements);
            break;
        case 3:
            var bk = 0;
            child.data.replace(regex, function(all) 
            {
                var args = [].slice.call(arguments),
                    offset = args[args.length - 2],
                    newTextNode = child.splitText(offset+bk), tag;
                bk -= child.data.length + all.length;

                newTextNode.data = newTextNode.data.substr(all.length);
                tag = callback.apply(window, [child].concat(args));
                child.parentNode.insertBefore(tag, newTextNode);
                child = newTextNode;
            });
            regex.lastIndex = 0;
            break;
        }
        child = child.nextSibling;
    }

    return node;
};

matchText(document.body, new RegExp("(?:(?:\\+|0{0,2})91(\\s*[\\- ]\\s*)?|[0 ]?)?[789]\\d{9}|(\\d[ -]?){10}\\d", "g"), function(node, match, offset) {
    var newAnchor = document.createElement("a");
    newAnchor.className = "search-term";
    //newAnchor.textContent = match;
    newAnchor.href = "tel:" + match.replace( /(\s|-)/g, "");
    newAnchor.innerHTML = '<img src =' + chrome.extension.getURL("call_icon_10x10.png")+'> ' + match;
    return newAnchor;
});

【讨论】:

  • 由于我之前的代码擦除了一些文本节点内容,我正确地修改了代码。它工作正常。引用自stackoverflow.com/questions/16662393/…链接
  • 此方法将成为救命稻草,因为它会一直运行,因此对于每个人打印的页面,它已经更改为正确的 zip 和电话号码,但正如您所看到的,这是文本,我仍在尝试找出替换数字
  • 您能澄清一下文本和替换发生的位置吗?添加(在此处放置文本)放置(此处为替换文本)
猜你喜欢
  • 2016-04-17
  • 1970-01-01
  • 2018-06-21
  • 1970-01-01
  • 2021-06-15
  • 2011-09-28
  • 2013-12-26
  • 1970-01-01
  • 2013-06-11
相关资源
最近更新 更多