Run Code After Function is Finished OR DIV Appears
-
28-09-2019 - |
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?
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);