【问题标题】:jQuery ajax, wait until beforeSend animation finishesjQuery ajax,等到 beforeSend 动画完成
【发布时间】:2011-07-09 22:27:28
【问题描述】:

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
});

问题是,error 函数开始,在 beforeSend 函数中的动画结束之前。

这是工作示例http://jsfiddle.net/H4Jtk/2/

error 应该在beforeSend 完成后才开始工作。 如何做到这一点?

我使用beforeSend 函数在ajax 启动时启动块的动画。我无法删除它。

谢谢。

【问题讨论】:

    标签: javascript jquery html css ajax


    【解决方案1】:

    您可以使用自定义事件等待动画完成,如下所示:

    $("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
    });
    

    注意事项:

    1. jQuery.one() 附加一个事件处理程序,该处理程序触发一次然后被删除。
    2. jQuery.is(':animated') 是 jQuery 提供的自定义选择器,用于确定元素是否使用 jQuery 的内置动画方法(例如 fadeIn)进行动画处理。

    新的 jsFiddle:http://jsfiddle.net/pgjHx/


    在 cmets 中,Happy 曾询问如何处理多个动画。一种方法是向animationComplete 事件处理程序添加条件以查看动画是否正在进行。例如:

    $("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
    });
    

    【讨论】:

    • 我想在没有 is(:animated) jsfiddle.net/H4Jtk/4 的情况下使用它很好
    • +1 for is(':animated'),你能告诉我在哪里可以找到有关此事件“animationComplete”的更多信息吗?刚刚搜索了一下,但没有发现任何有用的信息。
    • @Happy,您可以将事件排队(请参阅api.jquery.com/animate 上的队列选项),然后在最后一个动画中触发“animationComplete”事件,或者您可以维护某种活动计数器动画(例如,将var animationCount = 0 添加到单击事件处理程序的顶部,然后在每次调用动画的上方添加animationCount++,然后将animationCount--; if(animationCount &gt; 0) return 添加到animationComplete 处理程序的开头)。
    • @Praveen,我只是在创建一个自定义事件处理程序和一个自定义事件名称;在 DOM 或 jQuery 中没有原生的 animationComplete 事件,我只是选择了它作为描述性名称。
    • @eyelidlessness 你是摇滚明星!
    【解决方案2】:

    你可以这样做

    //在链接点击时运行你的动画,当动画完成时, // 然后开始你的 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
                });
        });
    });
    

    【讨论】:

    • 此解决方案将 XHR 请求延迟了 600 毫秒,这是一个明显的延迟。我明白为什么快乐不想这样做了。
    【解决方案3】:

    问题是“beforeSend”完成 - 它会在“fadeIn”完成之前很久就退出。我不知道您要完成什么,因此很难提供解决方案。如果您想保证首先发生,您必须等到动画序列(“fadeIn”)完成之后才开始 ajax 操作。

    【讨论】:

    • 我使用 beforeSend 函数在 ajax 启动时启动块的动画。动画完成后,我通过向后动画显示有关成功数据的错误消息。现在更清楚了吗?
    • Happy 正在尝试完成: 1. XHR 调用立即触发; 2. beforeSend 处理程序负责处理在 XHR 请求开始时发生的操作;和 3. error 事件等待 beforeSend 操作完成,然后再使 DOM 更改无序。根据我的回答,这可以通过自定义事件来完成,而不会延迟 XHR 请求。
    猜你喜欢
    • 1970-01-01
    • 2017-03-15
    • 2014-03-06
    • 2012-08-23
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 2015-07-19
    • 2013-04-09
    相关资源
    最近更新 更多