OP question:
As I understand it, the steps of its application (in a real context) are as follows:
- User selects an option from the menu
- The loading image is enabled
- A request is made for AJAX
- In AJAX's success callback the loading image is disabled
Your problem is that sometimes the user changes the selection more quickly than the animation.
In terms of user experience, it has some relatively simple solutions ...
Accelerate the animation. Instead of "slow" use "fast" or specify the milliseconds directly (slow is 600ms, fast is 200ms)
Use show()
and hide()
instead of fadeIn
and fadeOut
. It stops being animated and happens to be instantaneous.
Another, more complex way is to listen the ajaxStop event .
This event fires when there are no more AJAX requests on the stack.
$( document ).ajaxStop(function() {
ajaxLoadAni('Out');
});
So, it's only when all ajax requests are finished that the animation is hidden. If you combine this with one of the solutions I presented or the suggestion suggested by Paulo Roberto, the user experience improves.
Multiple order problem:
However, assuming that the schematization I made of the steps in your application is correct, there is a bigger problem, which is the number of AJAX calls that can be triggered almost simultaneously.
For example, if you use the arrows to change the select and alternately press the up and down keys 25 times, you will have 25 almost simultaneous AJAX requests in a very short space of time. If you do it 2500 times ... imagine.
Solution to the problem of multiple requests:
The simplest (and cleanest) solution would be to add a button that calls the function that does the AJAX request, instead of listening to the " change " event of in> "
$('.ajaxBtn').click(function () {
//Chamar ajax aqui
});
You can also disable select while the ajax request has not been completed, but this can worsen the user experience.
Another way to keep the interface as it is would be to place a flag that would prevent multiple AJAX requests from firing at the same time and only when the previous one was resolved would you accept a new one.
var ajaxFlag = false;
$("select[name=meuSelect]").change(function(event) {
event.preventDefault();
var valor = $(this).val();
if (ajaxFlag === false) {
ajaxLoadAni('In');
ajaxFlag = true;
//Funcao AJAX
$.ajax()
.success(function() //Quando é bem sucessida
{
$("#valor").text(valor);
})
//.error() //QUando dá erro
.complete(function() //é sempre chamada
{
ajaxLoadAni('Out');
ajaxFlag = false;
})
}
});
The problem with this solution is that it desynchronizes the select menu, that is, if I quickly change the option, it will ignore the second option and show only the first one, although in the select menu you select the second one.
You also have the option to delay between the selection and the ajax request.