如何让Chrome扩展按钮与注入的js进行通信? [英] How to have chrome extension button communicate with injected js?

查看:362
本文介绍了如何让Chrome扩展按钮与注入的js进行通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Chrome扩展,它将一个js文件注入一个网页。在浏览器中单击时也会打开一个弹出窗口。在弹出窗口中有一个按钮应该改变js文件中的一个变量。但注入的文件通常无法与扩展的其余部分进行通信。我如何改变这种情况?



我仍然对chrome扩展有点新,感谢您的帮助。



编辑:这是我到目前为止



清单文件:

 <$ 
manifest_version:2,
name:Minds Color Extension,
version:1,
content_scripts:[
{
matches:[https://www.minds.com/*],
js:[injectedjs.js],
css:[injectcss.css]
}
],
browser_action:{
$ b $default_icon:{
19 :icon.png,
38:icon.png
},
default_title:头脑通知页面,
default_popup:popup .html



}

Popup.html

 <! -  
<!doctype html>
单击扩展按钮时会显示此页面,因为manifest.json中的
browser_action字段包含带有
值popup.html的default_popup键。
- >
< html>
< head>
< title> Minds Theme Extension< / title>
< style>
html,body {
margin:0;
填充:10;
width:250px;
}
#blue {
background-color:#337dff;
}
#orange {
background-color:#ff5733;
}
#dark {
background-color:#4a505b;
}
按钮{
border:none;
颜色:白色;
padding:10px 27px;
text-align:center;
text-decoration:none;
display:inline-block;
font-size:16px;
margin:4px 2px;
光标:指针;
}
#footer {
position:fixed;
bottom:0;
}
< / style>

<! - -
- JavaScript和HTML必须位于单独的文件中:有关详细信息和说明,请参阅我们的Content Security
- 策略文档[1]。
-
- [1]:https://developer.chrome.com/extensions/contentSecurityPolicy
- >
< script src =injectedjs.js>< / script>
< / head>
< body>
< div id =status>
< h2>选择一个主题:< / h2>
< a href =blue.html>< button type =buttonid =blueonclick =activeBlue(); run();> Blue< / button>< / A>
< a href =orange.html>< button type =buttonid =orangeonclick =activeOrange(); run();> Orange< / button>< / A>
< a href =dark.html>< button type =buttonid =darkonclick =activeDark(); run();>黑暗< / button>< / A>
< br />
< div id =footer>
< font size =1> < a href =mailto:one.snapp8@gmail.com?Subject = Minds%20Supporttarget =_ top>联系我们< / a>< / font>
< / div>
< / div>
< / body>
< / html>

Injectedjs.js

  // Var块
var blue = 0;
var orange = 0;
var dark = 0;

//激活块
函数activeBlue(){
blue = 1;
}
函数activeOrange(){
orange = 1;
}
函数activeDark(){
dark = 1;
}

//重置var块
函数reset(){
blue = 0;
orange = 0;
dark = 0;
}

//改变头脑css(运行主题)
函数run(){
if(blue == 1){
//运行代码将改变蓝色。
document.getElementById(mdl-color - white)。className =mdl-color - blue;
}
if(orange == 1){
//运行代码将把头脑改为橙色
document.getElementById(mdl-color - white)。className =mdl-color - orange;
}
if(dark == 1){
//运行代码将会改变主意为黑暗
document.getElementById(mdl-color - white)。className =mdl-color - grey;


$ b

Injectedcss.css中没有任何内容。如果你需要像dark.html这样的其他文件,我可以给你,但我不明白为什么你需要它们。

解决方案

要理解的重要事情是注入脚本与网页交互,但与弹出窗口(或背景)中发生的情况分开。因此,虽然您将inject.js列为内容脚本并通过popup.html加载,但它们实际上最终会成为两个单独的文件。



因此,第一步将是创建一个popup.js。它需要附加点击监听器(onclick计算为不分隔javascript和html),并使用消息传递 a>告诉内容脚本要做什么。 (我也整理了一下你的逻辑。)

  [blue,orange,gray]。的forEach(addListenerFor); 

函数addListenerFor(color){
document.getElementById(color)
.addEventListener(click,turnPage.bind(undefined,color);
}

函数turnPage(color){
chrome.tabs.query({active:true,currentWindow:true},function(tabs){
chrome.tabs.sendMessage(标签[0] .id,{newClass:mdl-color - + color});
});
}


  chrome.runtime.onMessage.addListener(changeClass); 

function changeClass(message){
reset();
if(message.newClass) {
document.getElementById(mdl-color-white)。className = message.newClass;
}
}
$ b $ p

一些最终想法:


  • 由于您的扩展程序针对特定页面,我们应该使用页面操作而不是浏览器操作重要的是(你的扩展根本不会出现)。这些日子,它会使你无法打开弹出窗口,除非你在正确的页面上。

  • 如果你的inject.css是真的空的,那么你可以简单地删除 manifest.conent_scripts 条目中的 css 键。
  • 为了使 getElementById 在popup.js中工作,您需要在元素存在后运行脚本。您可以将所有内容放入 onload 调用中,但移动脚本可能更容易标记到 body 关闭之前。


I have a chrome extension that injects a js file into a webpage. And also open a popup when clicked in the browser. In the popup there is a button that should change a variable in the js file. But the injected file usually cant communicate with the rest of the extension. How do i change this?

I'm still a bit new to chrome extensions, thank you for your help.

EDIT: Here is what i have so far

Manifest file:

     {
    "manifest_version": 2,
    "name": "Minds Color Extension",
    "version": "1",
"content_scripts": [
    {
      "matches": ["https://www.minds.com/*"], 
      "js": ["injectedjs.js"],
      "css" : ["injectedcss.css"]
    }
],
        "browser_action": {

          "default_icon": { 
            "19": "icon.png",
            "38": "icon.png"
          },
          "default_title": "Minds Notification page",
          "default_popup": "popup.html"

        }

      }

Popup.html

<!--
<!doctype html>
 This page is shown when the extension button is clicked, because the
 "browser_action" field in manifest.json contains the "default_popup" key with
 value "popup.html".
 -->
<html>
  <head>
    <title>Minds Theme Extension</title>
    <style>
html, body {
margin:0;
padding:10;
width: 250px;
}
   #blue {
    background-color: #337dff;
}
   #orange {
    background-color: #ff5733;
}
   #dark {
    background-color: #4a505b;
}
    button {
    border: none;
    color: white;
    padding: 10px 27px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
}
#footer {
position: fixed;
bottom: 0;
}
    </style>

    <!--
      - JavaScript and HTML must be in separate files: see our Content Security
      - Policy documentation[1] for details and explanation.
      -
      - [1]: https://developer.chrome.com/extensions/contentSecurityPolicy
     -->
    <script src="injectedjs.js"></script>
  </head>
  <body>
    <div id="status">
<h2> Pick a theme: </h2>
<a href="blue.html"><button type="button" id="blue" onclick="activeBlue(); run();">Blue</button></a>
<a href="orange.html"><button type="button" id="orange" onclick="activeOrange(); run();">Orange</button></a> 
<a href="dark.html"><button type="button" id="dark" onclick="activeDark(); run();">Dark</button></a>
<br />
<div id="footer">
<font size="1"> <a href="mailto:one.snapp8@gmail.com?Subject=Minds%20Support" target="_top">Contact us</a></font>
</div>
</div>
</body>
</html>

Injectedjs.js

// Var block
var blue = 0;
var orange = 0;
var dark = 0;

// Activation block
function activeBlue() {
blue = 1;
}
function activeOrange() {
orange = 1;
}
function activeDark() {
dark = 1;
}

// Resets var block
function reset() {
blue = 0;
orange = 0;
dark = 0;
}

//Changes Minds css (Runs theme)
function run() {
if (blue == 1) {
    // Runs code that will change minds to blue. 
document.getElementById("mdl-color--white").className = "mdl-color--blue";
} 
if (orange == 1) {
    // Runs code that will change minds to orange
document.getElementById("mdl-color--white").className = "mdl-color--orange";
} 
if (dark == 1) {
    // Runs code that will change minds to dark
document.getElementById("mdl-color--white").className = "mdl-color--grey";

} 
}

Injectedcss.css has nothing in it. If you need the other files like dark.html i can give them to you but i dont see why you'd need them.

解决方案

The big thing to understand is that an injected script interacts with a webpage, but is separate from what happens in your popup (or your background). So while you have injected.js listed as a content script and loaded by popup.html, they actually end up as two separate files.

So the first step will be to create a popup.js. It needs to attach the click listener ("onclick" counts as not separating javascript and html) and use message passing to tell the content script what to do. (I’ve also consolidated your logic a bit.)

["blue","orange","grey"].forEach(addListenerFor);

function addListenerFor(color) {
  document.getElementById(color)
    .addEventListener(click,turnPage.bind(undefined,color);
}

function turnPage(color) {
  chrome.tabs.query({"active": true, "currentWindow": true}, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, {"newClass": "mdl-color--"+color});
  });
}

Within the content script, we need to listen for the message and take the appropriate action:

chrome.runtime.onMessage.addListener(changeClass);

function changeClass(message) {
  reset();
  if ( message.newClass ) {
    document.getElementById("mdl-color--white").className = message.newClass;
  }
}

Some final thoughts:

  • Since your extension targets a specific page, you’re supposed to use a page action instead of a browser action. The difference used to be more important (your extension wouldn't appear at all). These days it would make it so that you can’t open the popup unless you’re on the right page.
  • If your injected.css is truly empty, then you can simply remove the css key from the manifest.conent_scripts entry.
  • In order for getElementById to work in popup.js, you need to run the script after the element is present. You could put everything into an onload call, but it's probably easier to move your script tag to just before body closes.

这篇关于如何让Chrome扩展按钮与注入的js进行通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆