尝试在chrome扩展(JavaScript)中从default_script到content_script进行通信无法正常工作

war*_*ing 7 javascript google-chrome communication google-chrome-extension content-script

好吧,所以我通过扩展程序更改网站的配色方案,这是我第一次使用content_scripts所以是的,我是一个完整的新手,随意把我当作一个人.

问题是tabs.connect它不工作,我需要标签ID或什么?这是我到目前为止所拥有的:

manifest.json的:

{
  "manifest_version": 2,

  "name": "ROBLOX Color Scheme",
  "description": "Edit the color scheme of the roblox bar! Note: Not created by roblox.",
  "version": "1.0",

  "permissions": [
    "<all_urls>",
    "tabs"
  ],
  "browser_action": {
    "default_icon": "Icon.png",
    "default_popup": "Popup.html"
  },
  "content_scripts": [
    {
      "matches": ["http://www.roblox.com/*"],
      "js": ["ContentScript.js"]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

Popup.html:

<!DOCTYPE html>
<html>
    <head>
        <p>Choose a color:</p>
        <input type="color" id="Color" value="">
        <button type="button" id="Button">Change Color!</button>
    </head>
    <body>
        <script src="Script.js"></script>
    </body>

</html>
Run Code Online (Sandbox Code Playgroud)

的script.js:

function ChangeColor() {
  var TabId;
    chrome.tabs.query({currentWindow: true, active: true}, function(tabArray) {
      TabId = tabArray[0];
    });
  var port = chrome.tabs.connect(TabId, {name: "ColorShare"});
  port.postMessage({Color: document.getElementById("Color").value});
}

document.getElementById('Color').addEventListener("click", ChangeColor);
Run Code Online (Sandbox Code Playgroud)

ContentScript.js:

var Color;
chrome.runtime.onConnect.addListener(function(port) {
  if (port.name == "ColorShare") then {
    port.onMessage.addListener(function(msg) {
      Color = msg.Color;
    });
  }
});

document.getElementsByClassName("header-2014 clearfix")[0].style.backgroundColor = Color;
Run Code Online (Sandbox Code Playgroud)

所有的帮助表示赞赏,感谢您花时间回答我的问题!

编辑:有些文件已经改变了,感谢我自己和一个回答的人的帮助,这些现在没有产生任何错误,但没有任何改变,任何你可能提供的帮助都会很棒!以下是当前的代码:

的script.js:

chrome.tabs.query({currentWindow: true, active: true}, function(tabArray) {
    var TabId = tabArray[0].id;
    var port = chrome.tabs.connect(TabId, {name: "ColorShare"});

    function ChangeColor() {
        port.postMessage({Color: document.getElementById("Color").value});
    }
    document.getElementById('Color').addEventListener("click", ChangeColor);
});
Run Code Online (Sandbox Code Playgroud)

ContentScript.js:

chrome.runtime.onConnect.addListener(function(port) {
    if (port.name == "ColorShare") {
        port.onMessage.addListener(function(msg) {
            document.querySelector("header-2014 clearfix").style.backgroundColor = msg.Color;
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

编辑:这个问题解决了.我不得不使用chrome.storage.sync.set和chrome.storage.sync.get,它完全支持内容脚本!我将发布很快使用的脚本!

Tee*_*emm 4

我认为您\xe2\x80\x99误解了端口的概念。一个端口用于会话中的多个消息。但是当会话结束时(例如,当选项卡关闭时),端口将被销毁。无论如何,您不应该在每次单击时重新创建端口。

\n\n

您的评论之一提到刷新页面,这让我认为您希望这种颜色在页面重新加载时保持不变。从用户界面的角度来看,这是有道理的,但您确实应该在一开始就提到这一点。

\n\n

正如我所说,当选项卡关闭(或重新加载)时,端口会被破坏。如果您希望该值持续存在,您\xe2\x80\x99将需要一个存储机制,例如chrome.storage(您也可以使用本地存储,但前面的链接给出了不这样做的几个原因)。

\n\n

manifest.json 只需要"permissions": [ "activeTab", "storage" ],. 您可能还需要页面操作而不是浏览器操作(或者两者都不需要,我\xe2\x80\x99会做到这一点)。

\n\n

ContentScript.js:\n

\n\n
var myBgColor = false;\n\nchrome.storage.sync.get("myBgColor",function(items) {\n    if ( items.myBgColor ) {\n        myBgColor = items.myBgColor;\n        document.querySelector(".navbar").style.backgroundColor = myBgColor;\n    }\n});\n\nchrome.runtime.onMessage.addListener(function(request,sender,sendResponse) {\n    if ( request.setColor ) {\n        document.querySelector(".navbar").style.backgroundColor = request.setColor;\n        chrome.storage.sync.set({"myBgColor":request.setColor});\n    } else if ( request.getColor ) {\n        sendResponse({"myBgColor":myBgColor});\n    }\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

我将参数更改为querySelector,因为我无法\xe2\x80\x99 在索引页上找到您要查找的元素。

\n\n

弹出窗口.html:\n

\n\n
<!DOCTYPE html>\n<html>\n<body>\n<p>Choose a color:</p>\n<input type="color" id="color" value="">\n<button type="button" id="button">Change Color!</button>\n<script src="Script.js"></script>\n</body>\n</html>\n
Run Code Online (Sandbox Code Playgroud)\n\n

I\xe2\x80\x99m 不确定为什么你的输入位于页面的头部。

\n\n

Script.js(但请将您的文件重命名为比 Script.js 更具描述性的名称):\n

\n\n
document.getElementById(\'button\').addEventListener("click",function() {\n    chrome.tabs.query({currentWindow: true, active: true},function(tabArray) {\n        chrome.tabs.sendMessage(tabArray[0].id,{"setColor":document.getElementById("color").value});\n    });\n});\n\nchrome.tabs.query({currentWindow: true, active: true}, function(tabArray) {\n    chrome.tabs.sendMessage(tabArray[0].id,{"getColor":1},setCurColor);\n});\n\nfunction setCurColor(response) {\n    if ( response.myBgColor ) {\n        document.getElementById("color").value = response.myBgColor;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果存在先前设置的背景颜色,我们\xe2\x80\x99d 希望有ContentScript.js加载消息。Script.js不幸的是,Script.js仅当我们\xe2\x80\x99单击操作图标时才存在。所以我们有Script.jsContentScript.js当前颜色(如果已设置\xe2\x80\x99s)。

\n\n

正如 Ruwanka Madhushan 注意到的那样,您的原始脚本(部分)失败了,因为您假设异步chrome.tabs.query将在继续执行下一行代码之前完成。异步 JavaScript 非常强大,但它给了你不假设代码已经完成的责任。您\xe2\x80\x99将需要使用嵌套函数调用,要么匿名(如Script.js\xe2\x80\x99s onclick),要么通过命名实用函数(如setCurColor)。(还有一些 JavaScript 库可以帮助异步函数,但我不知道它们。)

\n\n

一切正常,但\xe2\x80\x99s有一个小问题:Popup.html在失去焦点时关闭- 在这种情况下,当您单击颜色选择器输入时。(非常糟糕的)解决方法是打开弹出窗口并右键单击并选择 \xe2\x80\x9cInspect Element\xe2\x80\x9d。这将打开弹出窗口的控制台,并防止弹出窗口在您选择颜色时关闭。另一种选择可能是将颜色选择器嵌入到弹出窗口内的 iframe 中(我不知道这是否可行)。

\n\n

但由于我们\xe2\x80\x99正在讨论您的扩展选项,因此最好的替代方案可能是使用选项页面。这也将为您的 html 提供更多空间。例如,您可能需要考虑使用一个按钮来删除 localStorage.myBgColor,以便可以恢复默认值。或者其他自定义站点的选项,因为我\xe2\x80\x99m希望你\xe2\x80\x99不会仅仅为了改变颜色而遇到所有这些麻烦。它会隐藏操作图标,因为您\xe2\x80\x99可能会设置选项,然后想要忘记现有的扩展。

\n