jQuery ajax, espere hasta que termine la animación finaliza

HTML y CSS:

link  
img { display: none; } a { display: block; }

JS:

 $("a").click(function(){ $.ajax({ url: "test.php", contentType: "html", beforeSend: function(){ $("img").fadeIn(600, function(){ $("div").append(" | beforeSend finished | "); }); }, error: function(){ $("div").append(" | error | "); } }); return false }); 

El problema es que error inicia la función de error antes de que beforeSend animación en la función beforeSend .

Aquí está el ejemplo de trabajo http://jsfiddle.net/H4Jtk/2/

error debería comenzar a funcionar solo cuando beforeSend haya finalizado. ¿Como hacer esto?

beforeSend función beforeSend para iniciar la animación de los bloques cuando comienza ajax. No puedo eliminarlo

Gracias.

Puede usar un evento personalizado para esperar hasta que la animación se complete, como esta:

 $("a").click(function(){ var img = $("img"), div = $("div"); $.ajax({ url: "test.php", contentType: "html", beforeSend: function(){ img.fadeIn(600, function(){ div.append(" | beforeSend finished | "); div.trigger("animationComplete"); }); }, error: function(){ if(img.is(':animated')) { div.one("animationComplete", function() { div.append(" | error | "); }); } else { div.append(" | error | "); } } }); return false }); 

Notas:

  1. jQuery.one() adjunta un controlador de eventos que se dispara una vez y luego se elimina.
  2. jQuery.is(':animated') es un selector personalizado proporcionado por jQuery para determinar si un elemento está animado utilizando los métodos de animación incorporados de jQuery (por ejemplo, fadeIn ).

Nuevo jsFiddle: http://jsfiddle.net/pgjHx/


En los comentarios, Happy ha preguntado cómo manejar múltiples animaciones. Una forma sería agregar una condición al controlador de eventos animationComplete para ver si la animación está en curso. Por ejemplo:

 $("a").click(function(){ var img = $("img"), div = $("div"); $.ajax({ url: "test.php", contentType: "html", beforeSend: function(){ img.fadeIn(600, function(){ div.append(" | beforeSend finished | "); div.trigger("animationComplete"); }); // Add another animation just to demonstrate waiting for more than one animation img.animate({ marginTop: '-=5', opacity: '-=.5' }, 700, function() { div.trigger("animationComplete"); }); }, error: function(){ if(img.is(":animated")) { // Note I've switched to bind, because it shouldn't be unbound // until all animations complete div.bind("animationComplete", function() { if(img.is(":animated")) { return; } div.append(" | error | "); div.unbind("animationComplete"); }); } else { div.append(" | error | "); } } }); return false }); 

Puedes hacerlo

// ejecuta su animación en el enlace clic, y cuando la animación se completa, // entonces comienza su solicitud de Ajax.

 $("a").click(function () { $("img").fadeIn(600, function () { $("div").append(" | beforeSend finished | "); $.ajax({ url: "test.php", contentType: "html", error: function () { $("div").append(" | error | "); } }); return false }); }); }); 

Lo que pasa es que “beforeSend” está terminado: saldrá mucho antes de que termine “fadeIn”. No sé lo que estás tratando de lograr, por lo que es difícil ofrecer una solución. Tendrías que esperar para comenzar la operación de Ajax hasta que la secuencia de animación (el “fadeIn”) finalice si quieres garantizar que eso suceda primero.