LINUX.ORG.RU

Анимация с jQuery, почему она асинхронная?

 ,


0

1

Хочу понять, почему следующий код анимирует оба дива одновременно, а не последовательно, в порядке вызовов. Это какая-то фишка jQuery или сам яваскрипт такой, что второе if выполняется не дожидаясь возвратов из функций вызванных в первом?

function showDiv( sidebarDiv, mainContentDiv ) {
	if ( mainContentDiv ) {
		$( "div[id$='main-content-div']:visible" ).slideUp( 250, function(){
			$( "#" + mainContentDiv ).slideDown( 250 );
		});
		if ( sidebarDiv ) {
			if ( $( "div[id$='sidebar-div']" ).is(":visible") ) {
				$( "div[id$='sidebar-div']:visible" ).slideUp( 250, function(){
					$( '#' + sidebarDiv ).slideDown( 250 );
				});
			} else {
				$( '#' + sidebarDiv ).slideDown( 250 );
			};
		};
	};
};



Последнее исправление: varchar (всего исправлений: 1)

Ответ на: комментарий от ritsufag

Т. е.

второе if выполняется не дожидаясь возвратов из функций вызванных в первом?

А если б после первого условия, функцией изменялась бы глобальная переменная, которая проверялась бы вторым условием... Яваскрипт так умён?

varchar
() автор топика
Ответ на: комментарий от varchar

А если б после первого условия, функцией изменялась бы глобальная переменная, которая проверялась бы вторым условием... Яваскрипт так умён?

Нет, это ты не умеешь использовать событийную модель. JS не будет ничего ждать и твоя функция в slideUp запустится когда будет на это свободная возможность. Может даже когда эта твоя функция showDiv уже давно отработает.

Используй коллбеки к slideUp и в них уже ставь свои проверки или думай о другой архитектуре кода, без использования событий и отложенных вызовов.

BaBL ★★★★★
()
Последнее исправление: BaBL (всего исправлений: 1)
Ответ на: комментарий от BaBL

Другими словами, асинхронные функции (здесь slideUp, slideDown) отрабатывают ~мгновенно, а не через 250 мс. Соответственно следующий за ними код выполняется сразу же.

anonymous
()
Ответ на: комментарий от BaBL

Спасибо, позволь уточнить правильно ли понял, что jquery мою безымянную делает отложенной и спросить, - что здесь событие?

varchar
() автор топика
Ответ на: комментарий от anonymous

Альтернатива callback'ам: http://api.jquery.com/promise/

The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended.

By default, type is «fx», which means the returned Promise is resolved when all animations of the selected elements have completed.

Так что если нужно будет много анимации, можно попробовать с помощью обещаний написать более плоский код.

anonymous
()
Ответ на: комментарий от varchar

Спасибо, позволь уточнить правильно ли понял, что jquery мою безымянную делает отложенной и спросить, - что здесь событие?

твоя безымянная - это как раз и есть коллбек на событие комплита слайдапа. Т.е. внутри безымянной у тебя код выполнится по завершении работы слайдапа.

А вот проверка условия - выполнится сразу после начала слайдапа и пойдет в параллели. Если ты проверку хочешь после - либо setTimeout на то же значение 250 (что кривой костыль), либо запихни этот иф внутрь коллбека, если это ничему не противоречит у тебя.

function showDiv( sidebarDiv, mainContentDiv ) {
	if ( mainContentDiv ) {
		$( "div[id$='main-content-div']:visible" ).slideUp( 250, function(){
			$( "#" + mainContentDiv ).slideDown( 250 );
			if ( sidebarDiv ) {
				if ( $( "div[id$='sidebar-div']" ).is(":visible") ) {
					$( "div[id$='sidebar-div']:visible" ).slideUp( 250, function(){
						$( '#' + sidebarDiv ).slideDown( 250 );
					});
				} else {
					$( '#' + sidebarDiv ).slideDown( 250 );
				};
			};
		});
	};
};
BaBL ★★★★★
()
Ответ на: комментарий от BaBL

Тут вот ещё какое дело - иногда, после частых кликов по триггерам к showDiv(), блоки которым положено скрыться остаются видимыми, вместе с только что показанными. Как так? Ведь показ скрытого блока в каллбэке к скрытию видимого.

Пробовал .promise(), так, чтобы showDiv() была по завершении всех анимаций

$(":animated").promise().done(function() { тут showDiv() });
а та же фигня случается...

varchar
() автор топика
Ответ на: комментарий от varchar

Тут вот ещё какое дело - иногда, после частых кликов по триггерам к showDiv(), блоки которым положено скрыться остаются видимыми, вместе с только что показанными. Как так? Ведь показ скрытого блока в каллбэке к скрытию видимого.

А, ну тут наверно параллельное выполнение одной функции в двух экземплярах. Пока одна уже в процессе но ещё не показала второй нечего скрывать и она тоже показывает. Попробовать очередь, что ли...

varchar
() автор топика
Ответ на: комментарий от varchar

Подожди... Как это нечего скрывать? Показ же в каллбэке к скрытию видимого! Ничего не понимаю.

varchar
() автор топика
Ответ на: комментарий от varchar

Добавь .stop().slideUp везде, это уберет много багов. А вообше, лучше не обрабатывать хендлер, пока процесс идет.

BaBL ★★★★★
()
Ответ на: комментарий от BaBL

Ага, спасибо.

$(":animated").finish();
перед слайд-ап-даунами всё решила. Две (ну, или сколько успевал накликать) функций скрывали один и тот же элемент, а показывали каждая свой.

Таким же нубам как я - алерты для отладки отстой.

console.log()
!

varchar
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.