从新的 dom 按钮调用内容脚本函数

Call content script function from new dom button

这是一个非常简单的例子:

manifest.json

{
  ...
  "content_scripts": [
    {
      "js": [
        "/js/external/jquery-2.1.3.min.js", 
        "/js/content_script.js"
      ],
      ...
    }
  ],
  ...
}

content_script.js

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

$(function() {
  $( "body" ).prepend( 
    "<input type=\"button\" value=\"Press me\" onclick=\"demo()\" />"
  );
});

我在控制台中收到此错误:

Uncaught ReferenceError: demo is not defined

如何使功能正常工作?

这里的问题是Isolated Worlds

内容脚本有自己的 JS 上下文。您在内容脚本上下文中定义 demo

但是,当添加这样的 DOM 节点时,onclick 属性将引用没有 demo 功能的页面上下文。

这里有很多选择。

  1. 最简单的是在content script context中给节点附加一个监听器:

    var node = $('<input type="button" value="Press me"/>').click(demo);
    $("body").prepend(node);
    
  2. 另一种方法是在页面上下文中定义demo()。为此,您需要通过 <script> 标签 inject the code to the page context

    var script = document.createElement('script');
    script.textContent = demo.toString();
    (document.head||document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
    

    请注意,此代码无法访问内容脚本上下文和 Chrome API。但是,它可能会有用,因为它可以访问页面自己的 JavaScript.

  3. 如果您需要两者的混合(访问页面和内容脚本),则需要 make the two contexts communicate.

var node = $('<input type="button" value="Press me"/>').click(demo);
$("body").prepend(node);

另一种方法是在页面上下文中定义demo()。为此,您需要通过 <script> 标记将代码注入页面上下文。