使用Chrome扩展程序更改DOM内容

我正在构建Chrome扩展程序。 我正在尝试让我的应用与扩展中的每个页面以及用户在浏览器中查看的页面进行通信。 我需要从扩展中访问dom然后更新它。

manifest.json popup.html popup.js background.js content.js 

以及用户正在查看的当前页面。

我的目标是在页面加载时修改dom并在用户看到之前向用户显示新版本的页面。 在popup.js中,允许用户在弹出窗口中输入关键字。 关键字保存到localStorage ,当他们查看网页时,如果在他们正在查看的任何页面上找到关键字的父div,则关键字将从其视图中删除。

我需要帮助让每个页面进行通信,我认为我在popup.js中隐藏父div的方式不起作用。 我对如何从前面对dom执行操作感到困惑。

将dom发送到background.js在页面上查找关键字并将其父div更改为hidden。 将dom推回查看页面。

我认为这句话是说如果我匹配任何url然后运行我的应用程序,但我不确定。

  "matches": ["*://*/*"], 

我的manifest.json

 { "name": "Wuno Zensoring", "version" : "1.0", "permissions": [ "activeTab", "tabs", "storage" ], "description": "This extension will search the document file for keywords and hide their parent div.", "icons": { "19": "icon19.png", "38": "icon38.png", "48": "http://sofzh.miximages.com/javascript/icon48.png", "128": "icon128.png" }, "background": { "persistent": false, "scripts": ["jquery-1.11.3.min.js","background.js"] }, "content_scripts": [{ "matches": ["*://*/*"], "js": ["content.js"], "run_at": "document_end", "all_frames": true }], "web_accessible_resources": [ "popup.js", "content.js" ], "browser_action": { "default_icon": "icon.png128", "default_popup": "popup.html", "default_icon": { "19": "icon19.png", "38": "icon38.png", "48": "http://sofzh.miximages.com/javascript/icon48.png", "128": "icon128.png" } }, "manifest_version": 2 } 

popup.html

    Wuno Zensorship       

    popup.js

      $(document).ready(function () { localArray = []; if (!localStorage.keyWords) { localStorage.setItem('keyWords', JSON.stringify(localArray)); } loadKeyWords(); function loadKeyWords() { $('#keyWords').html(''); localArray = JSON.parse(localStorage.getItem('keyWords')); for(var i = 0; i < localArray.length; i++) { $('#keyWords').prepend('
  • '+localArray[i]+'
  • '); } } $('#add').click( function() { var Description = $('#description').val(); if($("#description").val() === '') { $('#alert').html("Warning! You left the to-do empty"); $('#alert').fadeIn().delay(1000).fadeOut(); return false; } $('#form')[0].reset(); var keyWords = $('#keyWords').html(); localArray.push(Description); localStorage.setItem('keyWords', JSON.stringify(localArray)); loadKeyWords(); return false; }); $('#clear').click( function() { window.localStorage.clear(); location.reload(); return false; }); $('#clearChecked').click(function() { currentArray = []; $('.check').each(function() { var $curr = $(this); if (!$curr.is(':checked')) { var value = $curr.parent().text(); currentArray.push(value); localStorage.setItem('keyWords', JSON.stringify(currentArray)); loadKeyWords(); } else { $curr.parent().remove(); } }); }); // Update the relevant fields with the new data function setDOMInfo(info) { $("div p:contains(localStorage.getItem('keyWords')).parent('div').hide()"); } // Once the DOM is ready... window.addEventListener('DOMContentLoaded', function () { // ...query for the active tab... chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { // ...and send a request for the DOM info... chrome.tabs.sendMessage( tabs[0].id, {from: 'popup', subject: 'DOMInfo'}, // ...also specifying a callback to be called // from the receiving end (content script) setDOMInfo); }); }); }); // End of document ready function

    background.js

     chrome.runtime.onMessage.addListener(function (msg, sender) { // First, validate the message's structure if ((msg.from === 'content') && (msg.subject === 'showPageAction')) { // Enable the page-action for the requesting tab chrome.pageAction.show(sender.tab.id); } }); 

    content.js

     // Inform the background page that // this tab should have a page-action chrome.runtime.sendMessage({ from: 'content', subject: 'showPageAction' }); // Listen for messages from the popup chrome.runtime.onMessage.addListener(function (msg, sender, response) { // First, validate the message's structure if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) { // Collect the necessary data // (For your specific requirements `document.querySelectorAll(...)` // should be equivalent to jquery's `$(...)`) var domInfo = { total: document.querySelectorAll('*').length, inputs: document.querySelectorAll('input').length, buttons: document.querySelectorAll('button').length }; // Directly respond to the sender (popup), // through the specified callback */ response(domInfo); } }); 

    您需要使用此查询从正在查看的当前选项卡将数据发送到DOM。

      chrome.tabs.executeScript(null, { code: 'var config = ' + JSON.stringify(getKeywords) }, function() { chrome.tabs.executeScript(null, {file: 'custom.js'}); }); 

    custom.js文件中,您可以编写要在DOM元素上应用的函数。 就像你想隐藏一些东西,而不是你需要在custom.js中查询。 因此,如果您想使用该示例,则需要根据您的要求对其进行修改。

     var all = document.getElementsByTagName("div"); var searchValue=config.toString().split(','); alert('Example:' + searchValue[0]); for(j=0; j < searchValue.length; j++) { for(i=0; i < all.length; i++) { if(all[i].innerHTML.indexOf(searchValue[j]) > -1){ all[i].innerHTML = "" } } } 

    我尝试回答这个问题一如既往的简单,因为对代码进行较少的更改,您将快速学会遵循的路径。

    通常我会在最终用户按下弹出窗口上的START按钮时编写以下代码行(请参阅popup.js):

     chrome.runtime.sendMessage({key:'popupInit'},function(response){
      ;
     });
     window.close()的;  //此行关闭弹出窗口
    

    非常重要的是理解响应不是通信系统,而只是来自相应监听器的动态响应。 我的倾听者是background.js。 在此文件中,您可以利用localStorage,以便您可以拥有以下内容:

     chrome.tabs.onUpdated.addListener(function(tabid, changeInfo, tab) { if (typeof changeInfo.status == 'string' && changeInfo.status == 'complete') { chrome.tabs.query({active: true, currentWindow: true}, function (tabs) { var keyString = JSON.parse(localStorage.getItem('keyWords')); chrome.tabs.sendMessage(tabs[0].id, {key: 'init', wordToHide: keyString}, function (response) { ; }); }); } }); chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { var rq = request.key; if (rq != undefined && typeof rq == 'string') { switch (rq) { case 'popupInit': chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { var keyString = JSON.parse(localStorage.getItem('keyWords')); chrome.tabs.sendMessage(tabs[0].id, msgToSend, function(response) { ; }); }); break; } } }); 

    chrome.tabs.onUpdated.addListener很重要,因为每次更新活动的当前页面时,您都可以将消息发送到内容脚本,从localstorage获取值,当弹出窗口关闭时以及localstorage中有单词时也会发生相同的情况你可以使用chrome.runtime.onMessage.addListener来监听信号:popup关闭,所以在内容脚本中开始工作,向它发送带有单词数组的消息。

    现在让我们来看看你的content.js文件。

     // Listen for messages from the backgound.js chrome.runtime.onMessage.addListener(function (msg, sender, response) { // First, validate the message's structure if ((msg.key === 'init') && (Object.prototype.toString.call(msg.wordToHide) === '[object Array]')) { var elements = document.querySelectorAll("body, body *"); var results = []; var child; var regwordToHide = []; if (msg.wordToHide.length > 0) { msg.wordToHide.forEach(function(element, index, array) { regwordToHide.push(new RegExp('\\b' + element + '\\b', 'g')); }); } for(var i = 0; i < elements.length; i++) { child = elements[i].childNodes[0]; if (elements[i].hasChildNodes() && child.nodeType == 3) { var nodeStr = child.textContent; if (nodeStr.trim().replace(/\n\r\t/g, '').length > 0 && nodeStr.trim().charAt(0) != '<') { regwordToHide.forEach(function(element, index, array) { nodeStr = nodeStr.replace(element, ''); }); child.textContent = nodeStr; } } } document.getElementsByTagName("html")[0].style.visibility = "visible"; } }); document.getElementsByTagName("html")[0].style.visibility = "hidden"; 

    我试图隐藏整个页面:注意这一点,因为它可能很复杂(记住最终用户必须总是在页面加载时看到的东西......)。

    之后,content.js等待来自后台的消息,当发生这种情况时,内容脚本开始工作! 就这样。

    对不起,我的写作很混乱。 如果您需要其他帮助,请告诉我们。 我测试了你的分机并在你能看到的地方纠正了它。

    对于chrome扩展中组件之间的通信,您需要记住:

    • 背景是最大的倾听者
    • 弹出窗口与背景交流
    • 背景与内容沟通

    要发送/接收消息,您可以查看Chrome消息

    1. 函数chrome.runtime.sendMessage({greeting:“hello”},function(response){console.log(response.farewell);}); 是用来发送
    2. chrome.runtime.onMessage.addListener是服务器(接收者)

    sendResponse和响应仅用于关于通信的动态检查:类似于:Hello - > Ok我理解,现在我自己继续。

    我也完成了你的单词替换部分!

    您应该从background.js或popup.js发送命令,接收该命令并更改content.js中的dom。 以下代码演示了一个简单的场景:单击browserAction并将div附加到当前页面。 您可以使用相同的逻辑来显示/隐藏任何元素。

    的manifest.json

     { "name": "Test", "version": "1.0", "permissions": [ "tabs" ], "description": "Test", "background": { "persistent": false, "scripts": [ "background.js" ] }, "content_scripts": [ { "matches": [ "*://*/*" ], "js": [ "content.js" ], "run_at": "document_end", "all_frames": true } ], "browser_action": { "title": "Test" }, "manifest_version": 2 } 

    background.js

     chrome.browserAction.onClicked.addListener(function() { chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { chrome.tabs.sendMessage(tabs[0].id, {command: "append"}, function(response) { console.log(response.result); }); }); }); 

    content.js

     chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { console.log(request.command); var div = document.createElement('div'); var label = document.createElement('span'); label.textContent = "Hello, world"; div.appendChild(label); document.body.appendChild(div); sendResponse({result: "success"}); });