Question

I have written a Userscript for Facebook and it groups similar notifications together. Now, using just a static HTML page with old notifications I had, the script works 100%.

Here's the problem: the DIV that holds notifications by default, has no notifications in it until the user clicks on the Notification button. Facebook has an inline onclick event that displays the DIV (Notifications menu) and uses AJAX to grab the notifications. Since my userscript only runs on startup, it finds nothing there - it has no effect on the page. I tried using a .click() event but right when you click the Notifications button it runs my code. The thing is, Facebook is still running it's AJAX request for the notifications, meaning that there are still no notifications for my script to work with, making it have no effect.

I don't want to use a generic setTimeout because I don't want the user to have to see the notifications before and then suddenly see them after. Is there a way to monitor the DIV so once the notifications are added, it runs? Or that once Facebook finishes it's AJAX request, it will run my code?

Was it helpful?

Solution

You can setInterval() to monitor the div's innerHTML, once populated you can run.

OTHER TIPS

Here's the problem: the DIV that holds notifications by default, has no notifications in it until the user clicks on the Notification button. Facebook has an inline onclick event that displays the DIV (Notifications menu) and uses AJAX to grab the notifications.

...

I don't want to use a generic setTimeout because I don't want the user to have to see the notifications before and then suddenly see them after. Is there a way to monitor the DIV so once the notifications are added, it runs?

Yes there is:

var notificationDiv = document.getElementById(...);
var lastTimeoutID = null;
var main = function(evt){
  // evt.target is the inserted element
  // if you expect more elements, then do the following:
  lastTimeoutID = setTimeout(function(){
    lastTimeoutID = null;
    // uncomment below block if you only need to do the work once.
    /*
    notificationDiv.removeEventListener("DOMNodeInserted", main, false);
    */

    // do your work here.
  }, 500); // waiting 500ms for next element to be added, otherwise doing work.
  if (lastTimeoutID) {
    clearTimeout(lastTimeoutID);
    lastTimeoutID = null;
  }
};
notificationDiv.addEventListener("DOMNodeInserted", main, false);

All of the timeout code above might be removable depending on what it is you're userscript is doing.

Maybe you can add a setTimeout loop. Something like

setTimeout(function(){
/* check for divs */

if(/* divs are found */){
//apply code
}
else {
setTimeout(/* loop again */);
}

},1000);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top