Question

I've used jQuery's ajaxSend and ajaxStop to show a spinner whenever ajax requests are active. It works except when some of my plugins abort their ajax requests, ajaxStop does not trigger and will not trigger until after the page is refreshed. It seems like the aborted request still counts to jQuery. Can I make ajaxStop trigger or is there a better way?

Was it helpful?

Solution

Well I figured out a way that I quite like. Patch the XMLHttpRequest abort method so that it will decrease jQuery's ajax counter and trigger the handler if it's the last request. Not sure yet how well it will work across browsers.

var old_abort = XMLHttpRequest.prototype.abort;
XMLHttpRequest.prototype.abort = function(){
    jQuery.proxy(old_abort, this)();
    if ( jQuery.active-- === 1 )
        jQuery.event.trigger( "ajaxStop" );
};

OTHER TIPS

This seems to only be an issue in jQuery 1.4.2 for dataType = "json", see http://forum.jquery.com/topic/ajaxstart-not-fired-when-jquery-active-changes-from-0-to-1

Upgrade to jQuery 1.5.1 or apply the patch posted by Jake above. Also, I had to modify the patch as follows before it would work correctly for my use cases:

f_abort = XMLHttpRequest.prototype.abort;
XMLHttpRequest.prototype.abort = function() {
  $.proxy(f_abort, this)();
  if ($.active === 1) {
    $.event.trigger("ajaxStop");
    $.active = 0;
  } else if ($.active > 1) {
    $.active--;
  }
};

I would use the complete event instead - that runs no matter what:

complete (Local Event)
This event is called regardless of if the request was successful, or not. You will always receive a complete callback, even for synchronous requests.

$.ajax({
   complete: function(){
     // hide your spinner
   }
 });

not sure if you need this, but you can trigger the ajaxStop event. $(this).trigger('ajaxStop');

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top