1

I have created a chrome extension that uses the youtube api to trawl through comments and grab links. I then use chrome extensions content scripts to insert the results on to each youtube video page and convert the links to be clickable.

My problem is that the jquery document.ready is only firing so long as the previous page wasn't a video page watch/v= OR on a page refresh.

In other words clicking from one watch page to another watch page via youtubes own links doesn't cause the document.ready to fire.

It seems to be something to do with the way youtube loads watch pages now. Only the "?v=" parameter is changing and I am guessing youtube loads all the content in dynamically rather than reloading pages.

Is there an alternative to document.ready I could use?

$(document).ready(function() {

 app.insertLinksInit();

 });

I was thinking if there was a way to listen to change on window.location.href but from what I have read this doesn't seem to have events attached to it. What other events can I listen for to know the parameter in the url has changed? I am using jquery-2.0.3.min.

Paulie
  • 1,567
  • 4
  • 16
  • 21
  • 1
    See http://stackoverflow.com/questions/18397962/chrome-extension-is-not-loading-on-browser-navigation-at-youtube/18398921#18398921 – Rob W Sep 24 '13 at 09:40
  • Hey, I use a JS bridge to be able to monitor states of the youtube player on a Web View inside an iOS application. Since a few days back, the isReady notifications doesn't seem to trigger 100% of times. I think this has to do with the problem you are having. Do you know what changed on the API? – Pedro Mancheno Sep 24 '13 at 14:40

1 Answers1

0

If 'onready' doesn't help, most simple way is polling the page to find the chuck of code that you need and then launch the behaviour you need.

content-script.js

var regex = /\<a\s\w+/; //finds <a tags (for example) 

function polling(){
  if (regex.test(document.querySelector('#closest-id').innerHTML)) {
    // The regular expression produced a match, so notify the background page.
    chrome.extension.sendRequest({}, function(response) {});
  } else {
    //nothing found test again, delay it as long as possible
    setTimeout(polling,1000);
  }
}
polling();

background.js

function onRequest(request, sender, sendResponse) {
   // your actions here
};

// Listen for the content script to send a message to the background page.
chrome.extension.onRequest.addListener(onRequest);
Community
  • 1
  • 1
Enrique Paredes
  • 467
  • 3
  • 5
  • Please do NOT serialize the whole document at such a short interval. – Rob W Sep 24 '13 at 09:29
  • Totally agree, it's way too expensive serialize the whole document. if you know the part of the code reduce it with document.getElementById('selector').innerText – Enrique Paredes Sep 24 '13 at 09:36
  • 1
    You're still serializing the document's text content, then trying to parse HTML from it. When `innerText` or `textContent` is used, all HTML tags are stripped. If you want to find a HTML element, use the DOM API, e.g. with [`document.querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector) or `XPath`. – Rob W Sep 24 '13 at 09:39
  • I was thinking some kind of polling might be necessary. But I still don't understand why jquery document.ready does fire initially. Enrique Paredes says no document.ready for us but it is happening once for me. Why? – Paulie Sep 24 '13 at 09:58
  • Just a quick correction on the code Enrique posted. It should be setTimeout not setInterval and the integer and function params are the other way around. eg setTimeout(polling, 1000); – Paulie Sep 24 '13 at 10:11
  • statement about missed jQuery.onready is incorrect, it works in injected content scripts well. Another reason for its failure exists – Andrey Sep 24 '13 at 10:46
  • Yes document ready does indeed work Audrey. The actual reason it isn't firing again is shown in the link Rob W's link in his comment below my original question. Youtube is using pushstate for loading content between /watch pages. – Paulie Sep 25 '13 at 09:06