patternjavascriptMinor
Make loading icon appear only after 2 seconds
Viewed 0 times
aftericonmakesecondsloadingonlyappear
Problem
On any ajax calls made that take more than 2 seconds, I want a loading icon to appear. I have css that takes care of showing the loading icon when the 'loading' class is added to the body.
And here is the relevant code:
This seems to be working fine, but I'm wondering if this might get me into trouble if multiple actions are made at the same time to do different ajax operations, and is there a better way of doing this?
EDIT (Here's why I want to wait 2 seconds):
There are actions that show immediate feedback, however the ajax call takes a split second to process. I don't want the user to see the loading symbol flicker on and off in cases like this. I only want to show it when something is actually taking a long time. No reason for them to feel like the site is slow when they wouldn't otherwise notice any slow down.
And here is the relevant code:
var loadingIconOn = false;
$(document).on({
ajaxStart: function () {
loadingIconOn = true;
setTimeout(function () {
if(loadingIconOn == true)
$('body').addClass("loading");
}, 2000);
},
ajaxStop: function () {
$('body').removeClass("loading");
loadingIconOn = false;
}
});
This seems to be working fine, but I'm wondering if this might get me into trouble if multiple actions are made at the same time to do different ajax operations, and is there a better way of doing this?
EDIT (Here's why I want to wait 2 seconds):
There are actions that show immediate feedback, however the ajax call takes a split second to process. I don't want the user to see the loading symbol flicker on and off in cases like this. I only want to show it when something is actually taking a long time. No reason for them to feel like the site is slow when they wouldn't otherwise notice any slow down.
Solution
The
Th
From a UX standpoint, I would find it odd that you only want to display the loading icon until after 2 seconds have passed. This seems like a really long time to wait to give the user some feedback that something is happening in response to some action they have taken.
There is no reason to have your global
For example:
This also gives the advantage of having the function to delay then add the class specifically "scoped" to only be relevant to the
Note that you don't need to use a custom queue like
But, I find it best practice to keep animations related to a certain set of functionality within their own queues so as to minimize potential conflicts with effects you might add in the future. Like say you added some functionality in the future to change some of other property/class on `
ajaxStart() handler is only called if there are no other ajax requests currently in progress, so if there is already something in progress, the handler will never be fired.Th
ajaxStop() handler will only be called when a request completed and there are no other outstanding requests. So, theoretically, if you have ajax requests being fired every second, the loading icon could remain on your screen in perpetuity. If you are looking at building a heavily ajax-driven UI, it might not be too wise to rely on the global ajax functionality for this reason, as you have to then concern yourself with interaction of different ajax requests and how they may impact the user experience.From a UX standpoint, I would find it odd that you only want to display the loading icon until after 2 seconds have passed. This seems like a really long time to wait to give the user some feedback that something is happening in response to some action they have taken.
There is no reason to have your global
loadingIconOn variable at all. It would be preferable instead to work with jQuery queue functionality to give explicit control over how the animations are sequenced.For example:
$(document).on({
ajaxStart: function () {
$('body').delay(2000, 'loadingIcon').queue('loadingIcon', function() {
$(this).addClass('loading').dequeue();
});
},
ajaxStop: function () {
$('body').clearQueue('loadingIcon').removeClass('loading');
}
});This also gives the advantage of having the function to delay then add the class specifically "scoped" to only be relevant to the
body element as well as the opportunity to set up a specific queue (loadingIcon in this example), which deals only with this specific functionality.Note that you don't need to use a custom queue like
loadingicon. You could simplify this down by using the default fx queue, which would look like:$(document).on({
ajaxStart: function () {
$('body').delay(2000).queue(function() {
$(this).addClass('loading').dequeue();
});
},
ajaxStop: function () {
$('body').clearQueue().removeClass('loading');
}
});But, I find it best practice to keep animations related to a certain set of functionality within their own queues so as to minimize potential conflicts with effects you might add in the future. Like say you added some functionality in the future to change some of other property/class on `
, if the effects were in their own queue, they could be applied to the element simultaneously with the icon loading effect without causing undesirable interactions (obviously other than if they impact the same CSS properties in the loading` class).Code Snippets
$(document).on({
ajaxStart: function () {
$('body').delay(2000, 'loadingIcon').queue('loadingIcon', function() {
$(this).addClass('loading').dequeue();
});
},
ajaxStop: function () {
$('body').clearQueue('loadingIcon').removeClass('loading');
}
});$(document).on({
ajaxStart: function () {
$('body').delay(2000).queue(function() {
$(this).addClass('loading').dequeue();
});
},
ajaxStop: function () {
$('body').clearQueue().removeClass('loading');
}
});Context
StackExchange Code Review Q#158318, answer score: 4
Revisions (0)
No revisions yet.