I'd like to offer another solution to the AJAX problem that is more modern and elegant.
Brock's script, like most others, uses setInterval()
to check periodically (300ms), so it can't respond instantly and there is always a delay. And other solutions uses onload events, which will often fire earlier than you want on dynamic pages.
The solution: Use MutationObserver()
to directly listen for DOM changes to respond immediately after an element is inserted
(new MutationObserver(check)).observe(document, {childList: true, subtree: true});
function check(changes, observer) {
if(document.querySelector('#mySelector')) {
observer.disconnect();
// actions to perform after #mySelector is found
}
}
The check
function will fires immediately after every DOM change. This allows you to specify arbitrary trigger conditions so you can wait until the page is in the exact state required before you execute your own code.
Note that, this may be slow if the DOM changes very often or your condition takes a long time to evaluate, so instead of observing document
, try to limit the scope by observing a DOM subtree that's as small as possible.
This method is very general and can be applied to many situations. To respond multiple times, just don't disconnect the observer when triggered.
Another use case is if you're not looking for any specific element, but just waiting for the page to stop changing, you can combine this with a idle timer that gets reset when the page changes.
var observer = new MutationObserver(resetTimer);
var timer = setTimeout(action, 3000, observer); // wait for the page to stay still for 3 seconds
observer.observe(document, {childList: true, subtree: true});
// reset timer every time something changes
function resetTimer(changes, observer) {
clearTimeout(timer);
timer = setTimeout(action, 3000, observer);
}
function action(observer) {
observer.disconnect();
// code
}
You can listen for attribute and text changes as well. Just set attributes
and characterData
to true
in the options
observer.observe(document, {childList: true, attributes: true, characterData: true, subtree: true});