Question of the PO:
From what I understand, the steps of its application (in a real context) are as follows::
- User selects an option from the menu
- The loading image is enabled
- An AJAX request is made
- In AJAX’s Success callback the loading image is disabled
Your problem is that sometimes the user changes the selection faster than the animation.
In terms of user experience, it has some relatively simple solutions...
Accelerar 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 becomes instantaneous.
Another way, a little more complex would be to listen the ajaxStop event.
This event is triggered when there are no more AJAX requests on the stack.
$( document ).ajaxStop(function() {
ajaxLoadAni('Out');
});
Thus, it is only when all the 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.
Problem of multiple requests:
However, assuming that the schematic I did of the steps of your application is correct, there is a bigger problem, which is the number of AJAX calls that can be fired almost simultaneously.
For example, if you use arrows to change the select and press the top and bottom button alternately 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 orders:
The simplest (and cleanest) solution would be to add a button that calls the function that makes the AJAX request, instead of listening to the "change" Event do "select"
$('.ajaxBtn').click(function () {
//Chamar ajax aqui
});
You can also disable select while the ajax request is not finished, but this may make the user experience worse.
Another way to keep the interface as it is would be to put a "flag" that would prevent multiple AJAX requests from firing at the same time and only when the previous one was resolved would it 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 unincronizes the select menu, that is, if I change the option quickly, it will ignore the second option and only show the first one, although in the select menu it selects the second.
You also have the option to delay between selecting and requesting ajax.
I wonder if I could show you the relevant code?
– Tivie
This is the link http://jsfiddle.net/QZ9q8/1/ of the entire @Tivie code
– Marcelo Diniz
Thank you, I hadn’t seen
– Tivie
No crisis... if you change the select with the arrow keys is easier to understand.
– Marcelo Diniz
A
stop
before fadein would resolve? http://jsfiddle.net/QZ9q8/2/– bfavaretto
@bfavaretto resolves yes, lack a little knowledge even. Valew. Leave as an answer to can get better flagged right.
– Marcelo Diniz
@bfavaretto wouldn’t be a stop at fadeOut?
– Paulo Roberto Rosa
I know it’s not the focus, but remember a better way to use the
document.ready
, using IIFE - Immediately Invoked Function Expression (English). Example here. Hug.– Zanoldor