jQuery ajax,等到 beforeSend 动画完成

Posted

技术标签:

【中文标题】jQuery ajax,等到 beforeSend 动画完成【英文标题】:jQuery ajax, wait until beforeSend animation finishes 【发布时间】: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 启动时启动块的动画。我无法删除它。

谢谢。

【问题讨论】:

【参考方案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
);

注意事项:

    jQuery.one() 附加一个事件处理程序,该处理程序触发一次然后被删除。 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 请求。

以上是关于jQuery ajax,等到 beforeSend 动画完成的主要内容,如果未能解决你的问题,请参考以下文章

ajax中的beforesend参数说明

jQuery中Ajax事件beforesend及各参数含义

巧用Ajax的beforeSend 提高用户体验

巧用Ajax的beforeSend 提高用户体验

巧用Ajax的beforeSend 提高用户体验

巧用Ajax的beforeSend 提高用户体验