Что определяет порядок выполнения методов в цепочках jQuery?

Код HTML

<div id="foo">
    <h1>foo</h1>
    <p>Pellentesque habitant morbi tristique.</p>
</div>
<div id="bar">
    <h1>bar</h1>
</div>

Код jQuery

$('#bar').click(function () {
    $('#foo p').hide('slow').appendTo('#bar').show('slow');
})

Ожидаемый результат

При нажатии кнопки #bar

  • скрыть элемент p в #foo
  • добавить p в #bar
  • show p, который теперь является дочерним элементом #bar

Фактический результат

  • добавить p в #bar
  • скрыть элемент p в #foo
  • show p, который теперь является дочерним элементом #bar

Вопросы

  • Что определяет порядок выполнения методов в цепочках jQuery?
  • Как я могу гарантировать, что каждое событие завершится до следующего запуска?

Ответ 1

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

$('#bar').click(function () {
  $('#foo p').hide('slow', function(){
    $(this).appendTo('#bar').show('slow');
  });
});

Ответ 2

Чтобы убедиться, что вы выполняете что-то ПОСЛЕ эффекта, такого как скрыть или показать, используйте обратный вызов. http://docs.jquery.com/Effects/show#speedcallback

Добавить:

Винсент прав, исполнение на самом деле

  • начать скрывать элемент p в #foo (МЕДЛЕННО)
  • добавить p к #bar (в оснастке)
  • начните показывать p, который теперь является дочерним элементом #bar (МЕДЛЕННО)

То, что вы видели, было результатом эффекта

  • добавить p к #bar (выполняется)
  • скрыть элемент p в #foo (ЗАВЕРШЕНА)
  • show p, который теперь является дочерним элементом #bar (ЗАВЕРШЕНА)

Ответ 3

Ожидаемый результат правильный. Наблюдаемое поведение может быть результатом скрытия ( "медленного" ), которое выполняется асинхронно. Таким образом, он запускается во время следующего действия. Таким образом, кажется, что p сначала добавляется к #bar. Вы можете попробовать скрыть() без медленного просмотра, если это имеет значение.

Ответ 4

Довольно уверен, что он выполнен в том порядке, в котором вы его вызываете, он, вероятно, запускает часть скрыть, а через секунду она добавляется к этому другому элементу, но часть анимации уже началась, она занимает больше времени, чем миллисекунда, потому что вы установили ее "медленный", и он прыгает в непрозрачности от 1 до 0, от 1 до 0,9 до 0,8 в миллисекундах.

$.fn.hide = function() { alert('hiding'); return this; };
$.fn.appendTo = function() { alert('appending To') }
$('body').hide().appendTo('html')

Ответ 5

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

http://docs.jquery.com/Effects/show

http://docs.jquery.com/Effects/hide

Ответ 6

Скрыть асинхронно. Если вы хотите дождаться завершения, вам нужно поместить весь код, который вы хотите запустить после него, в функцию обратного вызова, которую вы передаете, чтобы скрыть как параметр.

Ответ 7

Вам нужно использовать обратный вызов, если вы хотите поставить в очередь другие методы, запускаемые после шоу, похожего на "Sixten Otto". Анимация show hide не будет ждать выполнения метода append. Он запускает отдельный поток с setInterval, в то время как в то же время вызывается другой код. Таким образом, результат, который вы получили, не является неожиданным.