javascript - 将网页文本中的匹配词更改为按钮

标签 javascript jquery google-chrome-extension

我正在尝试制作一个 Chrome 扩展程序,该扩展程序通过一个网站来寻找关键字,然后用按钮替换这些关键字。但是,当我更改文本时,图像路径已损坏。

// This is a content script (isolated environment)
//    It will have partial access to the chrome API
// TODO 
//    Consider adding a "run_at": "document_end" in the manifest... 
//      don't want to run before full load
//      Might also be able to do this via the chrome API 
console.log("Scraper Running");
var keywords = ["sword", "gold", "yellow", "blue", "green", "china", "civil", "state"];

// This will match the keywords with the page textx
// Will also create the necessary buttons
(function() {
  function runScraper() {
    console.log($('body'));
    for(var i = 0; i < keywords.length; i++){
     $("body:not([href]):not(:image)").html($("body:not([href]):not(:image)").html()
         .replace(new RegExp(keywords[i], "ig"),"<button> " + keywords[i] + " </button>"));
     console.log("Ran it " + i);
    }
  }
  function createResourceButton() {
    // Programatically create a button here

    // Really want to return the button
    return null;
  }
  function createActionButton() {
  }
  runScraper();
})();
// TODO create the functions that the buttons will call
//      These will pass data to the chrome extension (see message passing)
//      Or we can consider a hack like this: 
// "Building a Chrome Extension - Inject code in a page using a Content script"
// http://stackoverflow.com/questions/9515704

当前结果图片:

Wikipedia images will not load

最佳答案

您对这个问题的处理方式是错误的。为此,您需要遍历仅更改文本节点的文档,而不是所有节点的 HTML。

修改 this other answer of mine 中的代码, 下面的完整扩展将页面上所有匹配的词更改为按钮。

实际的扩展:

button-izing matching words in Wikipedia page used in image by OP

list .json

{
    "description": "Upon action button click, make all matching words buttons.",
    "manifest_version": 2,
    "name": "Button all matching words",
    "version": "0.1",

    "permissions": [
        "activeTab"
    ],

    "background": {
        "scripts": [
            "background.js"
        ]
    },

    "browser_action": {
        "default_icon": {
            "32": "myIcon.png"
        },
        "default_title": "Make Buttons of specified words"
    }
}

background.js:

chrome.browserAction.onClicked.addListener(function(tab) {
    //Inject the script to change the text of all matching words into buttons.
    chrome.tabs.executeScript(tab.id,{file: 'contentScript.js'});
});

contentScript.js:

(function(){
    var keywords = ["sword", "gold", "yellow", "blue", "green", "china", "civil", "state"];
    //Build the RegExp once. Doing it for every replace is inefficient.
    //  Build one RegExp that matches all of the words instead of multiple RegExp.
    var regExpText = '\\b(' + keywords.join('|') + ')\\b';
    console.log(regExpText);
    var myRegExp = new RegExp(regExpText ,'mgi');

    function handleTextNode(textNode) {
        if(textNode.nodeName !== '#text'
            || textNode.parentNode.nodeName === 'SCRIPT' 
            || textNode.parentNode.nodeName === 'STYLE'
        ) {
            //Don't do anything except on text nodes, which are not children 
            //  of <script> or <style>.
            return;
        }
        let origText = textNode.textContent;
        //Clear the regExp search, not doing so may cause issues if matching against
        //  identical strings after the first one.
        myRegExp.lastIndex = 0;
        let newHtml=origText.replace(myRegExp, '<button>$1</button>');
        //Only change the DOM if we actually made a replacement in the text.
        //Compare the strings, as it should be faster than a second RegExp operation and
        //  lets us use the RegExp in only one place for maintainability.
        if( newHtml !== origText) {
            let newSpan = document.createElement('span');
            newSpan.innerHTML = newHtml;
            textNode.parentNode.replaceChild(newSpan,textNode);
        }
    }

    //This assumes that you want all matching words in the document changed, without
    //  limiting it to only certain sub portions of the document (i.e. not 'not(a)').
    let textNodes = [];
    //Create a NodeIterator to get the text node descendants
    let nodeIter = document.createNodeIterator(document.body,NodeFilter.SHOW_TEXT);
    let currentNode;
    //Add text nodes found to list of text nodes to process below.
    while(currentNode = nodeIter.nextNode()) {
        textNodes.push(currentNode);
    }
    //Process each text node
    textNodes.forEach(function(el){
        handleTextNode(el);
    });
})();

myIcon.png:

Icojam-Weathy-24-tornado.png

handleTextNode 中用于更改文本节点的代码是根据 another answer of mine 中的代码修改的.

关于javascript - 将网页文本中的匹配词更改为按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40572679/

相关文章:

javascript - 使用 socket.IO 时如何让 console.log 在浏览器中工作?

javascript - Codeigniter 2.1,Jquery - 500 内部服务器错误

javascript - 通过 JavaScript 设置空值

javascript - 如何像 Google 那样将默认焦点放在网页的搜索栏上

javascript - 提取 id 的一部分

google-chrome-extension - Chrome 扩展程序未在 YouTube 的浏览器导航中加载

google-chrome - Chrome 扩展图像 Assets 未显示( list 版本 2)

javascript - 无法将子元素附加到单击的元素

javascript - 如何在不同的范围内重用变量?

iframe - Chrome 仅在某些网站上强制在框架上使用白色背景