2

This is a very trivial example:

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()\" />"
  );
});

I get this error in the console:

Uncaught ReferenceError: demo is not defined

How do I get the functionality to work?

Xan
  • 74,770
  • 16
  • 179
  • 206
Rasmus
  • 2,783
  • 2
  • 33
  • 43

2 Answers2

6

The problem here is Isolated Worlds.

Content scripts have their own JS context. You define demo in the content script context.

However, when adding a DOM node like that, the onclick attribute will refer to the page context, which does not have the demo function.

You have many options here.

  1. The simplest is to attach a listener to the node in the content script context:

    var node = $('<input type="button" value="Press me"/>').click(demo);
    $("body").prepend(node);
    
  2. Another way is to define demo() in the page context. To do that, you need to inject the code to the page context via a <script> tag.

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

    Do note that this code won't have access to content script context and Chrome API. However, it may be useful, as it will have access to page's own JavaScript.

  3. If you need a mix of two (access to both page and content script), you'll need to make the two contexts communicate.

Community
  • 1
  • 1
Xan
  • 74,770
  • 16
  • 179
  • 206
0
var node = $('<input type="button" value="Press me"/>').click(demo);
$("body").prepend(node);

Another way is to define demo() in the page context. To do that, you need to inject the code to the page context via a <script> tag.

bobbyrne01
  • 6,295
  • 19
  • 80
  • 150