Javascript 用 Chrome 内容脚本扩展替换网站中的文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5797661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:54:26  来源:igfitidea点击:

Replace text in website with Chrome content script extension

javascriptgoogle-chromereplacegoogle-chrome-extension

提问by Will Richardson

I would like to create Google Chrome extension. Its job is to replace a word with another on all websites.

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

I have the following manifest.json file:

我有以下 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"
    }
  ]
}

and the javascript in myscript.js is:

myscript.js 中的 javascript 是:

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

However this does not function.. and I cannot find a way to debug the content script, only the background.html

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

回答by Volomike

I took the example from JavaNut13 and Matt Curtis to create an alias hider extension for Reddit, and updated it for the new manifest 2. It looks for user on Reddit named "user1" and replaces it with "nobody". Modify as you need.

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

manifest.json

清单文件.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

我的脚本.js

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

回答by Will Richardson

I have actually written this in jQuery: (Making sure you have the correct include tag)

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

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

回答by mattsven

Replacing/changing text within the DOM on this scale should not be done with blunt HTML-regex replacement, which is very unsafe. You risk mutilating the HTML in the process.

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

What you need to do is loop over every TextNode (Node) within the document, modifying the text within them.

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

Your code will end up looking something like this:

您的代码最终将看起来像这样:

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);

回答by Eli Grey

Use the DOM and modify the dataof the appropriate Textnodes. E.g.

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

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

回答by Pankaj Vavadiya

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;
});