JQuery ajax, wait for the animation to complete before sending
HTML and CSS:
<a href="#">link</a> <img src="http://2.bp.blogspot.com/_OIHTbzY7a8I/TOaiTKLqszI/AAAAAAAAAHM/eb3iiOqxzKg/s640/Auto_Audi_Audi_concept_car_005130_.jpg" /> <div></div> 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 }); The problem is that the error function runs before the animation in beforeSend .
Here is a working example http://jsfiddle.net/H4Jtk/2/
error should only start working after completion of beforeSend . How to do it?
I use the beforeSend function to start block animation when ajax starts. I can not delete it.
Thanks.
You can use a custom event to wait for the animation to complete, for example:
$("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 }); Notes:
jQuery.one()attaches an event handler that fires once and then is deleted.jQuery.is(':animated')is a custom selector provided by jQuery to determine if an element is animated using jQuery's built-in animation methods (e.g.fadeIn).
New jsFiddle: http://jsfiddle.net/pgjHx/
In the comments, Happy asked how to handle multiple animations. One way is to add a condition to the animationComplete event handler to see if the animation continues. For instance:
$("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 }); You can do it
// start the animation when you click the link, and when the animation finishes, // then run your ajax request.
$("a").click(function () { $("img").fadeIn(600, function () { $("div").append(" | beforeSend finished | "); $.ajax({ url: "test.php", contentType: "html", error: function () { $("div").append(" | error | "); } }); return false }); }); }); The fact is that "beforeSend" finished - it will be released long before "fadeIn" ends. I donβt know what you are trying to accomplish, so itβs hard to offer a solution. You will need to wait to start the ajax operation until the animation sequence ("fadeIn") ends, if you want to ensure that this happens first.