简体   繁体   中英

jQuery ajax, wait until beforeSend animation finishes

HTML & 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, error function starts, before animation in beforeSend function finishes.

Here is working example http://jsfiddle.net/H4Jtk/2/

error should begin to work only when beforeSend is finished. How to do this?

I use beforeSend function to start animation of the blocks when ajax starts. I can't remove it.

Thanks.

You can use a custom event to wait until the animation is complete, like this:

$("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:

  1. jQuery.one() attaches an event handler that fires once and is then removed.
  2. jQuery.is(':animated') is a custom selector provided by jQuery to determine if an element is animated using jQuery's built-in animation methods (eg fadeIn ).

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


In the comments, Happy has asked how to handle multiple animations. One way would be to add a condition to the animationComplete event handler to see if animation is ongoing. 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");
            });

            // 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 this

//run your animation on link click, and when animation gets completed, // then start 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 thing is that "beforeSend" is finished - it will exit long before that "fadeIn" finishes. I don't know what you're trying to accomplish so it's hard to offer a solution. You'd have to wait to start the ajax operation until after the animation sequence (the "fadeIn") completes if you wanted to guarantee that to happen first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM