如何在Google扩展中切换content_scripts的开/关状态?

5

我有一个简单的扩展程序,它会在Chrome工具栏上显示图标并显示一个启用/禁用按钮。我想要给这个按钮添加功能,以便可以禁用或启用在访问Google网站时触发的content_script.js

popup.js

var setLayout = function(){
    var list = document.createElement('ul');

    var enable = document.createElement('li');
    enable.appendChild(document.createTextNode('Enable Script'));
    enable.onclick = function(){toggle(0)};

    var disable = document.createElement('li');
    disable.appendChild(document.createTextNode('Disable Script'));
    disable.onclick = function(){toggle(1)};

    list.appendChild(disable);
    document.body.appendChild(list);

    function toggle(n){
        list.removeChild( n == 0 ? enable : disable);
        list.appendChild(n == 0 ? disable : enable);
    }
};

document.addEventListener('DOMContentLoaded', setLayout, false);

manifest.json

{
  "manifest_version": 2,

  "name": "test",
  "description": "test",
  "version": "1.0",

  "browser_action": {
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": ["https://www.google.co.uk/"],
      "js": ["content_scripts.js"]
    }
  ]
}

content_scripts.js

(function(){
    alert('hello');
})();

我是一个新手,对于谷歌扩展一无所知,不知道该如何操作。我想在点击禁用/启用按钮后更改应用程序清单文件,但在阅读了谷歌官网上的文档后,找不到正确的命令来执行此操作。非常感谢您的帮助。
2个回答

2

经过一些研究,我发现可以通过使用背景页面sendMessagelocalstorage来解决这个问题。

背景页面作为popup.jscontent_scripts.js之间的通信器,它们位于两个不同的文档中,不能直接传递变量。

要在清单中启用背景页面,我添加了:

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

localstorage 是一种能够在本地保存变量的技术,即使浏览器关闭再打开,它也能够记住这些变量。因此,当启用/禁用按钮被点击时,它会设置localStorage['status'] = 1/0,这个值可以通过background.js访问并传递到content_scripts.js

为了设置localStorage变量,我已经将它添加到了popup.js中:

if(!localStorage.status) localStorage['status'] = 1;
toggle(2);
enable.onclick = function(){toggle(0)};
disable.onclick = function(){toggle(1)};
function toggle(n){
    if((n == 0) && (enable.parentNode == list)){
        list.removeChild(enable);
        list.appendChild(disable);
        localStorage.status = 1;
    }else if((n == 1) && (disable.parentNode == list)){
        list.removeChild(disable);
        list.appendChild(enable);
        localStorage.status = 0;
    }else if((n == 2) && (!list.hasChildNodes())){
        list.appendChild((localStorage.status == 1) ? disable : enable);
        chrome.browserAction.setIcon({path: (localStorage.status == 1) ? "icons/icon19.png" : "icons/icon19_disabled.png"});
    }else{
        return;
    }
}

为了将 localStorage.status 传递给 content_scripts.js,我需要在 content_scrips.js 上使用 sendMessage,当它被加载时发送请求消息到 background.js,并且在 background.js 上使用 onMessage 监听请求并将响应发送到 content_scripts.js,其中包含 localStorage.status 的值。 background.js:
chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.type == "status") sendResponse({status: localStorage.status});
});

content_scripts.js

var fn = function(){...};
chrome.runtime.sendMessage({type: "status"}, function(response) {
    if(response.status == 1) fn();
    return;
});

这就是全部内容,希望有人会觉得它有用。

1
尝试使用代码而不是清单文件注入内容脚本,类似于这样:
chrome.tabs.executeScript(null, {file: "content_script.js"});

你可以使用消息传递在后台页面和内容脚本之间进行通信,决定是否注入内容脚本,或者在内容脚本中使用if语句仅在扩展程序操作按钮设置的标志位时运行。
你可以使用浏览器动作事件来检测操作按钮何时被按下。

谢谢你的回答,但并没有太多帮助。我对 Google 扩展程序非常陌生。如果你能详细解释一下你的答案,或者展示如何在我的代码中应用你的解决方案,那就太好了。 - razz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接