I recently ran into a situation in which I needed to have something happen just after an AJAX request had completed. Initially that sounded like something that would not really be possible. Not wanting to resort to rapid polling I put a bit more time in to thinking of a solution and came up with this.

(function(){
    var origionalOpen = XMLHttpRequest.prototype.open;
    
    XMLHttpRequest.prototype.open = function(method, url, async, user, pass){
        this.addEventListener("readystatechange", function(event){
            if (this.readyState == 4 && this.status == 200){
                // Do custom stuff
            }
        });
        
        origionalOpen.call(this, method, url, async, user, pass);
    }
})();

This replaces the default open() function of the XMLHttpRequest object with our custom one that adds an extra event listener then calls the original function, which we stored a copy of earlier on, so the page script thinks nothing weird went on. We now effectively have an listener for the readystatechange event on all AJAX requests that will take place.

There is one extra thing that’s needed, you need to make sure your script runs before the page loads so that we catch all requests that happen. You can do that by adding @run-at document-start to the metadata block. Pretty neat.