15

I've got a chrome extension with a popup.html and an injected content script. With the injected content script I'm trying to access youtube's javascript API functions and it all works fine except for one: addEventListener.

The event listener of Youtube's javascript API listens for the state of the video to change. So if the end of the video is reached the state changes to 0.

var currentVideo = document.getElementById('movie_player');
currentVideo.addEventListener("onStateChange", "onytplayerStateChange");

function onytplayerStateChange() {
   console.log("The state of the player has changed");
}

This piece of code works just fine in a normal environment but it fails to work in content script. Why can't I catch changing events in my content script? Any ideas?

jefvlamings
  • 303
  • 1
  • 2
  • 10
  • possible duplicate of [Building a Chrome Extension with Youtube Events](http://stackoverflow.com/questions/9515704/building-a-chrome-extension-with-youtube-events) – Rob W Mar 19 '12 at 20:36

1 Answers1

13

Content scripts do not run in the scope of the current page. The event handler has to be injected via another <script> tag, as described in this answer: Building a Chrome Extension with Youtube Events:

var actualCode = 'function onytplayerStateChange() {'
               + '    console.log("The state of the player has changed");'
               + '}';

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

PS. The DOM is available to the content script, so binding the event handler does work.

Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Definitely a noob question but how do you insert code with different characters in the actualCode variable? I would like to add a url (http://www.example.com) but it returns "Unexpected string". – jefvlamings Mar 20 '12 at 07:36
  • @user1279300 See the linked answer for more details, including a more convenient method to include code ("Method 1"). When you place the code directly in the script, quotes, newlines and other special characters have to be escaped using a backslash. – Rob W Mar 20 '12 at 12:02
  • Thanks Rob. I'm sorry if I annoy you with these questions but here's another one. I actually want the event listener to communicate with the rest of the content script. I want a generated URL to open at the end of the video. So if current state = 0 -> go to a URL specified in the content script. Is there a way to dynamically add a variable in to the "actualCode" piece? – jefvlamings Mar 20 '12 at 14:07
  • @user1279300 In the linked answer, I linked to another answer ([Chrome extension - retrieving Gmail's original message](http://stackoverflow.com/a/9636008/938089?chrome-extension-retrieving-gmails-original-message)), where an example of communicating between an injected script and the extension is shown. That is required for communicating from the injected code with the content script. The reverse, Content Script > Injected script, can be achieved by injecting another ` – Rob W Mar 20 '12 at 14:16
  • Note in ES6, you can use backticks on that `actualCode` variable value instead of + concats. In ES5, you can use backslashes on the end of each line. https://stackoverflow.com/a/805113/105539 – Volomike Sep 16 '20 at 14:54