2015-04-01 5 views
1
<!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 одновременно?

+1

Http: // StackOverflow. com/questions/1594077/jquery-synchronous-animation возможно, этот вопрос помогает –

+0

Они технически выполняются по порядку, но они предназначены для неблокирования путем добавления функции таймера и обратного вызова. Простой способ проверить это - отладить код и пройти через каждую строку. Вы увидите, что каждый из них выполняется один за другим – heymega

+1

__Synchronous__ и __single-threaded__ - это не одно и то же. – Mathletics

ответ

1

На самом деле не существует одновременно. Запуск анимации не блокирует выполнение вашего кода. Они начинаются один за другим, но они работают «почти» одновременно. jQuery анимации на самом деле похожи на setInterval, они обновляют непрозрачность каждые X миллисекунд. но между этими кодами X ms выполняется. и ваши анимации начинаются между этим небольшим количеством времени.

Если вы не хотите, чтобы они были одновременными, вы должны запустить их в обратном вызове предыдущего.

Вот код, чтобы заставить их работать один за другим:

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

анимационные эффекты JQuery все без блокировки, которая чаще всего то, что вы хотите. (Остальная часть кода не должна прийти к остановке, потому что вы бежите длинную анимацию)

Если вы хотите последовательную анимацию, вы можете использовать обратные вызовы:

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

Если вы оживляющий на одном и том же объекте jQuery использует внутреннюю очередь, поэтому нет необходимости использовать обратные вызовы, то есть $('#a).hide(1000).show(1000) не будет пытаться скрывать и показывать объект одновременно.

2

Это думает, что это связанно с этой частью 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