JQuery и параллельные события
Давайте посмотрим на мой вопрос! У меня есть HTML-страница с 2 DIV. Оба они связаны с функцией jQuery, запускаемой при событиях щелчка. Итак, у нас есть div1 и div2. Здесь у нас есть код:
<div id="div1"></div>
<div id="div2"></div>
....
<script>
$('#div1').click(function(){
$('#div1').animate({some animations...},1000);
});
$('#div2').click(function(){
$('#div2').animate({something else...},1000);
});
</script>
Хорошо, моя проблема в том, что если пользователь пытается нажать на div1, div1 должен сделать анимацию, и это займет некоторое время... но если во время этой анимации пользователь попытается нажать на div2, этот щелчок не должен быть запущен пока анимация div1 не закончится. Сценарий, который я разместил, является лишь очень короткой моей версией, и я не могу изменить структуру этих функций. Я попытался использовать bind/unbind, но я не могу позволить divX ждать, пока другая анимация не остановится, потому что функция bind автоматически запускает событие, которое я прикрепляю к элементу. Вы можете мне помочь?
РЕДАКТИРОВАТЬ: просто чтобы убедиться, что все могут понять, предположим, что в моем примере у нас есть 5 делений, каждый с различными функциями, запускаемыми при событии щелчка. если я нажимаю div1, все остальные div должны быть отключены во время выполнения анимации, запускаемой div1, после завершения анимации их можно снова включить при событии click.... чтобы быть уверенным, что если я нажму на div1, затем, пока анимация не будет завершена, я могу щелкнуть все остальные div, но никакое событие не должно быть запущено.
3 ответа
По флажку вы можете определить, работает анимация или нет.
flag = false;
$("#div1").click(function() {
flag = true;
$( "#anim1" ).animate({
opacity: 0.25}, 1000, function() {
flag = false;
});
});
Вы можете заставить одну анимацию ждать завершения другой, используя отложенные объекты:
$('#div2').click(function() {
$('#div1').promise().done(function() {
$('#div2').animate(...);
});
});
.promise().done(...)
будет только запускать внутренний обратный вызов, когда какая-либо существующая анимация на #div1
завершено. Если их нет, это будет продолжено немедленно.
Смотрите http://jsfiddle.net/alnitak/NjCf4/
Кроме того, вы можете использовать .queue
:
$('#div1').queue(function(next) {
$('#div2').animate(...);
next();
});
Последний код поставит в очередь анимацию #div2
в конце текущей очереди для #div1
, Однако, если последующие дополнительные анимации ставятся в очередь на #div1
они все еще случатся позже.
Отложенный метод, вероятно, лучше, потому что 1) он позволяет вам ждать произвольного набора элементов, и 2) он специально ждет, пока все анимации не будут выполнены, вместо того, чтобы бросать новое действие в очередь.
Проблема здесь в том, что вы запускаете функции, которые занимают некоторое время (анимация может занять секунду или больше, пока она выполняется), и пока она выполняется, процесс блокируется.
Николас Закас рекомендует в своей книге "Высокопроизводительный Javascript" инкапсулировать длительные операции обработки в небольшие промежутки времени, чтобы эти операции не блокировали оставшуюся часть выполнения.
Основная идея заключается в использовании таймеров для разделения каждой операции, которая занимает более 50 мс. Я посмотрю, смогу ли я опубликовать здесь пример позже.