0

In my Content Script, I have an element (an a tag, to be more specific) and I need to add an event to it. The event handler, however, is defined in the page JS, and I dont know how to attach it to the event of my element in the extension. What I want to achieve is:

element.addEventListener("mouseover", pageFunction("foo", "bar"));

I have read other questions, like this one, which suggests injecting code or using location.href="javascript:pageFunction(); void 0"; but I dont see how I could apply them in my case.

JohnCalms
  • 87
  • 7
  • You're calling the function immediately in that line. Use `element.addEventListener("mouseover", () => pageFunction("foo", "bar"));` instead to call the function only when the listener is triggered. – Andy Oct 24 '18 at 13:39
  • iirc, aren't the content/page/background scripts sandboxed from each other? Can't you just add a new event handler to the content script and it will be ok? – Andy Oct 24 '18 at 13:44
  • I get `ReferenceError: pageFunction is not defined` when running your suggestion in first comment. Same error if running the code I provided in the question – JohnCalms Oct 24 '18 at 13:56
  • This looks useful: [Accessing page script objects from content scripts](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts#Accessing_page_script_objects_from_content_scripts) – Andy Oct 24 '18 at 13:59
  • It was useful indeed, thank you. Using `element.addEventListener("mouseover", window.wrappedJSObject.pageFunction("foo", "bar"));` did not return errors, and if I misstype the function name I get the previous error, so I would say it recognizes the function now. However, using F12 and Inspector, I can see the element still does not have an event associated. Would you have an idea? – JohnCalms Oct 24 '18 at 14:15
  • Try `element.addEventListener("mouseover", () => window.wrappedJSObject.pageFunction("foo", "bar"), false);` – Andy Oct 24 '18 at 14:18
  • Yup, that was exactly it. It works now. Many thanks. Would you like to add an answer so I can mark it as accepted? – JohnCalms Oct 24 '18 at 14:21

1 Answers1

0

According to the MDN reference there is a way for page and content scripts to communicate with each other.

In Firefox*, DOM objects in content scripts get an extra property wrappedJSObject. This is an "unwrapped" version of the object, which includes any changes made to that object by any page scripts.

Now, in your code, you're immediately calling the function rather than passing the listener a reference. To solve this you should wrap your function call in an arrow function to prevent this:

element.addEventListener("mouseover", () => window.wrappedJSObject.pageFunction("foo", "bar"), false);

∗ I couldn't find any information about whether this method should be used for Chrome too.

Andy
  • 61,948
  • 13
  • 68
  • 95
  • In Chrome you can do it only by putting the code into page DOM: [example](//stackoverflow.com/a/9517879) – wOxxOm Oct 24 '18 at 16:10