JQuery - 为啥 JQuery 动画是同时的?

Posted

技术标签:

【中文标题】JQuery - 为啥 JQuery 动画是同时的?【英文标题】:JQuery - Why is JQuery animation simultaneous?JQuery - 为什么 JQuery 动画是同时的? 【发布时间】:2015-06-06 01:48:20 【问题描述】:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(document).ready(function()
    $("#a").hide(1000);
    $("#b").hide(1000);
    $("#c").hide(1000);

);
</script>
</head>
<body>

<p id="a">Paragraph 1</p>
<p id="b">Paragraph 2</p>
<p id="c">Paragraph 3</p>


</body>
</html>

javascript 是单线程的,所以我认为函数是一个一个执行的。但是在上面的示例中,这三个段落似乎同时开始 hide 动画并同时结束,好像有三个线程各自运行一个不同的动画。为什么动画不是一个一个运行?

【问题讨论】:

***.com/questions/1594077/… 也许这个问题有帮助 它们在技术上是按顺序运行的,但它们被设计为通过添加创建计时器和回调函数来实现非阻塞。一个简单的测试方法是调试代码并逐步执行每一行。你会看到一个接一个地执行 同步单线程不是一回事。 【参考方案1】:

它认为它与jquery的这一部分有关

jQuery.timers = [];
jQuery.fx.tick = function() 
    var timer,
        i = 0,
        timers = jQuery.timers;

    fxNow = jQuery.now();

    for ( ; i < timers.length; i++ ) 
        timer = timers[ i ];
        // Checks the timer has not already been removed
        if ( !timer() && timers[ i ] === timer ) 
            timers.splice( i--, 1 );
        
    

    if ( !timers.length ) 
        jQuery.fx.stop();
    
    fxNow = undefined;
;

jQuery.fx.timer = function( timer ) 
    jQuery.timers.push( timer );
    if ( timer() ) 
        jQuery.fx.start();
     else 
        jQuery.timers.pop();
    
;

jQuery.fx.interval = 13;

jQuery.fx.start = function() 
    if ( !timerId ) 
        timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
    
;

jQuery.fx.stop = function() 
    clearInterval( timerId );
    timerId = null;
;

jQuery.fx.speeds = 
    slow: 600,
    fast: 200,
    // Default speed
    _default: 400
;

如你所见

setInterval( jQuery.fx.tick, jQuery.fx.interval );

这是非“阻塞”js

【讨论】:

【参考方案2】:

实际上并没有同时发生。启动动画不会阻止代码的执行。它们一个接一个地开始,但它们“几乎”同时运行。 jQuery 动画实际上类似于 setInterval,它们每 X 毫秒更新一次不透明度。但是在那些 X ms 代码之间正在运行。并且您的动画将在这段时间之间开始。

如果你不希望它们同时发生,你应该在前一个的回调中启动它们。

这是使它们一个接一个运行的代码:

$(".a").hide(1000, function() 
   $(".b").hide(1000, function() 
      ....

如果您想使用 async 库来使您的代码更干净(如果只使用 10 个元素会很脏),您可以使用 async https://github.com/caolan/async

async.eachSeries([$(".a"), $(".b"), $(".c")], function(elem, callback) 
   elem.hide(1000, callback);
);

【讨论】:

【参考方案3】:

jQuery 动画效果都是非阻塞的,这通常是你想要的。 (您的其余代码不应因为您正在运行较长的动画而停止)

如果你想要顺序动画,你可以使用回调:

$('#a').hide(1000, function() 
   $('#b').hide(1000, fn...);
);

如果您在同一个对象上制作动画,jQuery 在内部使用队列,因此无需使用回调,即$('#a).hide(1000).show(1000) 不会尝试同时隐藏和显示对象。

【讨论】:

以上是关于JQuery - 为啥 JQuery 动画是同时的?的主要内容,如果未能解决你的问题,请参考以下文章

Jquery - 为啥我的图像不会在鼠标悬停时动画?

为啥会发生此 JQuery 错误?动画不是函数

使用 jQuery 触发 CSS 摇动动画,每隔一段时间都有效……为啥?

为啥我的 jQuery 动画在基于 webkit 的浏览器中不稳定?

为啥 jQuery 必须接收 2 个对象:使用动画滚动整个页面时的 body 和 html?

同时滑动切换和动画(jQuery)