4

I'm writing a Chrome content script and when I inject this in the DOM:

"<a href='#' onclick='alert(\"Hi!\");return false;'>Hi</a>"

it works fine (the alert pops up when I click it), however if I create a function for the alert, it will say function undefined. Ex:

"<a href='#' onclick='alertPlease(\"Hi!\");return false;'>Hi</a>"

function alertPlease(x){
     alert(x);
}

All my code is the same content script js file.

Do I have to place whatever code that can be used after loading in another js file in the background? I tried adding a background page with the 'alertPlease();' function, but that didn't work either.

Any hint will be greatly appreciated!
Thanks!

pizzamiasucks
  • 41
  • 1
  • 2

3 Answers3

10

Content scripts run in an "isolated world." The webpage and content scripts can't see each other's JavaScript variables (although they can see the same DOM). When you add an onclick attribute within the DOM, the handler is created on the webpage's world, not your extension's world, so that code can't access the other function you defined. Instead of using an onclick handler, you should define your event listener in pure Javascript and then use addEventListener to attach it.

Isolated worlds are a feature to improve security and stability. Things are similar if you're developing within the Greasemonkey sandbox in Firefox.

yonran
  • 18,156
  • 8
  • 72
  • 97
  • Good answer! One thing to note though, you can't access those internal JavaScript variables normally. But you "can" see extract the pages JavaScript variables to your extension through messaging if you wanted to. – Mohamed Mansour Mar 02 '11 at 02:30
0

Doing one of these today with manifest version 3, I learned:

I can't append a button to the page and use

<button type="button" onclick="myContentScriptFunction();">Call CS Function</div>

But, in the content script, I can do vanilla

let loadButton = document.createElement('button');
loadButton.innerText = 'Call CS Function';
loadButton.addEventListener('click', myContentScriptFunction);
document.querySelector('body').append(loadButton);

or jQuery

let loadButton = $("<button type="button">Call CS Function</button>")
loadButton.on("click", myContentScriptFunction)
$("body").append(loadButton);

And both worked as expected with all code in the content script

Info Source: Chrome Extension Samples Example

KellyCode
  • 728
  • 6
  • 12
-1

Specify any scripts in the manifest.json file under "content_scripts"

{
  "name": "My Extension",
  "content_scripts": [{
    "matches": ["<all_urls>"],
    "css": ["style.css"],
    "js": ["jquery-1.5.js", "script.js"]
  }]
}
Nic Aitch
  • 628
  • 8
  • 14
  • It's there. The extension only has 1 js script, and that script has only 2 steps: inject the anchor tag with the onclick attr, and the function when it's clicked. It works if I use an inline alert. – pizzamiasucks Mar 02 '11 at 01:58
  • Hmm, I just use jQuery in my extension so I didn't run into this issue, but it appears that the only way to interact with js in the DOM is to inject script tags. Have a look at [this post](http://stackoverflow.com/questions/2303147/injecting-js-functions-into-the-page-from-a-greasemonkey-script-on-chrome); I think this may be what you are after. – Nic Aitch Mar 02 '11 at 02:18