• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

.js/jQuery RE: specifying ajax requests in ajaxStart

Upon initiating ajax request, I want to trigger an overlay ONLY if it takes more than 2 seconds.

My goal is to only trigger the overlay after 2 seconds, and only if the ajax request has not completed.

The following works.

Once it fires off an ajax request, it waits 2 seconds. If there is still an active ajax request, it triggers an overlay with a 'waiting' gif. Once ajax requests are done, it hides the overlay.

However, the logic is based on ANY active ajax requests. How can I write this to only fire for a specific request? This code is vulnerable to other background ajax requests that I don't want firing an overlay. I need this to only work for specific ajax requests. For instance, if I have an ajax request that fires in the background, but isn't critical to the UI experience, I don't want it triggering the overlay.


Code:
$(document).on({

  ajaxStart:function() {

    setTimeout(function(){
      if (jQuery.active === 1) {
        $body.addClass("loading");
      }
    }, 2000);

  },

  ajaxComplete: function() {$body.removeClass("loading"); }    

});
 
Instead of binding the ajaxStart to the document object you need bind it to the specific DOM element that you want.

For instance, all of the items on the page you want to have that behavior could have a data attribute like "data-fade-on-slow" and then your JS could look like

Code:
$("[data-fade-on-slow").on({

  ajaxStart:function() {

    setTimeout(function(){
      if (jQuery.active === 1) {
        $body.addClass("loading");
      }
    }, 2000);

  },

  ajaxComplete: function() {$body.removeClass("loading"); }    

});
 
You probably don't want to modify ajaxStart() or ajaxComplete() at all if you aren't looking to do this globally. You can do it like this for a single ajax request (untested):

Code:
var loading = setInterval(function(){
	$('body').addClass('loading');
},2000);
var promise = $.post('/here',{data:'stuff'});
promise.done(function(){
	clearInterval(loading);
	$('body').removeClass('loading');
});

To take it a step further and make it more easily reusable you could create a wrapper function call that handles the logic for you, so your ajax request would look more like this:


Code:
toggleLoading(true); // toggle on
var promise = $.post('/here',{data:'stuff'});
promise.done(function(){
	toggleLoading(false); // toggle off
});
 
Back
Top