JQuery - 为什么 JQuery 动画是同时进行的

JQuery - Why is JQuery animation simultaneous?

本文关键字:JQuery 为什么 动画      更新时间:2023-09-26
<!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动画,就好像有三个线程,每个线程运行一个不同的动画。为什么动画不一一运行?

它认为它与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。

没有真正的同时性。启动动画不会阻止代码的执行。它们一个接一个地启动,但它们"几乎"同时运行。jQuery动画实际上类似于setInterval,它们每X毫秒更新一次不透明度。但在这些 X 毫秒代码之间正在运行。您的动画将在这短时间内开始。

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

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

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

如果你想使用异步库来使你的代码更干净(对 10 个元素这样做会很脏(,你可以使用异步 https://github.com/caolan/async

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

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

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

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

如果你对同一个对象进行动画处理,jQuery 在内部使用队列,所以不需要使用回调,即 $('#a).hide(1000).show(1000)不会尝试同时隐藏和显示对象。