草庐IT

javascript - 尝试在 chrome 扩展程序(JavaScript)中从 default_script 到 content_script 的通信不起作用

coder 2024-07-24 原文

好吧,我正在通过扩展程序更改网站的配色方案,这是我第一次使用 content_scripts 所以是的,我是一个完全的新手,请随意对待我。

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

list .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"]
    }
  ]
}

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>

脚本.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);

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;

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

编辑:由于我自己和回答者的帮助,现在有些文件已经更改,这些文件现在没有错误,但没有任何变化,您可能提供的任何帮助都会很棒!以下是当前代码:

脚本.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);
});

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

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

最佳答案

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

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

正如我所说,关闭选项卡(或重新加载)时端口会被破坏。如果你想让这个值持久化,你需要一个存储机制,比如 chrome.storage (您也可以使用本地存储,但前面的链接给出了不这样做的几个原因)。

manifest.json 只需要 "permissions": [ "activeTab", "storage"],。您可能还需要页面操作而不是浏览器操作(或者两者都不想要,我会讲到)。

ContentScript.js:

var myBgColor = false;

chrome.storage.sync.get("myBgColor",function(items) {
    if ( items.myBgColor ) {
        myBgColor = items.myBgColor;
        document.querySelector(".navbar").style.backgroundColor = myBgColor;
    }
});

chrome.runtime.onMessage.addListener(function(request,sender,sendResponse) {
    if ( request.setColor ) {
        document.querySelector(".navbar").style.backgroundColor = request.setColor;
        chrome.storage.sync.set({"myBgColor":request.setColor});
    } else if ( request.getColor ) {
        sendResponse({"myBgColor":myBgColor});
    }
});

我将参数更改为 querySelector,因为我在索引页上找不到您要查找的元素。

Popup.html:

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

我不确定您为什么要在页面的头部输入内容。

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

document.getElementById('button').addEventListener("click",function() {
    chrome.tabs.query({currentWindow: true, active: true},function(tabArray) {
        chrome.tabs.sendMessage(tabArray[0].id,{"setColor":document.getElementById("color").value});
    });
});

chrome.tabs.query({currentWindow: true, active: true}, function(tabArray) {
    chrome.tabs.sendMessage(tabArray[0].id,{"getColor":1},setCurColor);
});

function setCurColor(response) {
    if ( response.myBgColor ) {
        document.getElementById("color").value = response.myBgColor;
    }
}

如果之前设置了背景颜色,我们希望 ContentScript.js 加载消息 Script.js。不幸的是,Script.js 仅在我们单击操作图标时才存在。所以我们让 Script.jsContentScript.js 询问当前颜色(如果已设置)。

正如 Ruwanka Madhushan 所注意到的,您的原始脚本失败(部分)是因为您假设异步 chrome.tabs.query 会在继续执行下一行代码之前完成。异步 javascript 非常强大,但它给了你不假设代码已经完成的责任。您需要使用嵌套函数调用,可以匿名(如 Script.js 的 onclick)或通过命名实用程序函数(如 setCurColor)。 (也有 javascript 库可以帮助处理异步函数,但我不知道。)

一切正常,但有一个小问题:Popup.html closes when it loses focus - 在这种情况下,当您单击颜色选择器输入时。 (非常糟糕的)解决方法是调出弹出窗口并右键单击并选择“检查元素”。这将调出弹出窗口的控制台,并防止弹出窗口在您选择颜色时关闭。另一种选择可能是将颜色选择器嵌入弹出窗口内的 iframe 中(我不知道这是否可行)。

但由于我们正在讨论您的扩展选项,最好的选择可能是使用 options page .这也将为您的 html 提供更多空间。例如,您可能需要考虑一个按钮来删除 localStorage.myBgColor,以便您可以恢复默认设置。或者其他自定义网站的选项,因为我希望你不会为了改变颜色而费尽心机。而且它会隐藏操作图标,因为您可能会设置您的选项,然后想忘记现有的扩展程序。

关于javascript - 尝试在 chrome 扩展程序(JavaScript)中从 default_script 到 content_script 的通信不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25588188/

有关javascript - 尝试在 chrome 扩展程序(JavaScript)中从 default_script 到 content_script 的通信不起作用的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  3. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  4. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  5. ruby-on-rails - bundler : not executable: script/delayed_job - 2

    我正在尝试在我的远程服务器上运行以下命令(通过capistrano或ssh):bundleexecRAILS_ENV=productionscript/delayed_jobstart但我收到此错误消息:bundler:notexecutable:script/delayed_job以前从未见过这个,谷歌也没有适合我的东西。知道可能是什么问题吗? 最佳答案 也许它没有运行权限?尝试运行这个命令chmod+xscript/delayed_job然后再次执行文件。 关于ruby-on-rai

  6. ruby-on-rails - 尝试设置 Amazon 的 S3 存储桶 : 403 Forbidden error & setting permissions - 2

    我正在关注Hartl的railstutorial.org并已到达11.4.4:Imageuploadinproduction.我做了什么:注册亚马逊网络服务在AmazonIdentityandAccessManagement中,我创建了一个用户。用户创建成功。在AmazonS3中,我创建了一个新存储桶。设置新存储桶的权限:权限:本教程指示“授予上一步创建的用户读写权限”。但是,在存储桶的“权限”下,未提及新用户名。我只能在每个人、经过身份验证的用户、日志传送、我和亚马逊似乎根据我的名字+数字创建的用户名之间进行选择。我已经通过选择经过身份验证的用户并选中了上传/删除和查看权限的框(而不

  7. ruby - 下载位置 Selenium-webdriver Cucumber Chrome - 2

    我将Cucumber与Ruby结合使用。通过Selenium-Webdriver在Chrome中运行测试时,我想将下载位置更改为测试文件夹而不是用户下载文件夹。我当前的chrome驱动程序是这样设置的:Capybara.default_driver=:seleniumCapybara.register_driver:seleniumdo|app|Capybara::Selenium::Driver.new(app,:browser=>:chrome,desired_capabilities:{'chromeOptions'=>{'args'=>%w{window-size=1920,1

  8. arrays - Ruby:尝试在哈希数组上获取 Enumerator 时,nil:NilClass 的未定义方法 `[]' - 2

    我正在尝试循环哈希数组。当我到达获取枚举器开始循环的位置时,出现以下错误:undefinedmethod`[]'fornil:NilClass我的代码如下所示:defextraireAttributs(attributsParam)classeTrouvee=falsescanTrouve=falseownerOSTrouve=falseownerAppTrouve=falseresultat=Hash.new(0)attributs=Array(attributsParam)attributs.eachdo|attribut|#CRASHESHERE!!!typeAttribut=a

  9. ruby - 混帐 & ruby : How can I unset the GIT_DIR variable from inside a ruby script? - 2

    我编写了一个非常简单的“部署”脚本,作为我的裸git存储库中的post-updateHook运行。变量如下livedomain=~/mydomain.comstagingdomain=~/stage.mydomain.comgitrepolocation=~/git.mydomain.com/thisrepo.git(bare)core=~/git.mydomain.com/thisrepo.gitcore==addedremoteintoeachlive&stagegitslive和stage都初始化了gitrepos(非裸),我已经将我的裸仓库作为远程添加到它们中的每一个(名为co

  10. ruby-on-rails - 尝试为 Rails 中的用户名验证编写 REGEX - 2

    我正在尝试用Ruby(Rails)编写一个正则表达式,以便用户名的字符仅包含数字和字母(也没有空格)。我有这个正则表达式,/^[a-zA-Z0-9]+$/,但它似乎没有用,我在Rails中收到一个错误,说“The如果正则表达式使用多行anchor(^或$),这可能会带来安全风险。您是要使用\A和\z,还是忘记添加:multiline=>true选项?"我的user.rb模型中此实现的完整代码是:classUser我做错了什么以及如何修复此正则表达式,使其仅对数字和字母有效而不对空格有效?谢谢。 最佳答案 简短回答:使用/\A[a-z

随机推荐