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 мс. Я посмотрю, смогу ли я опубликовать здесь пример позже.

Другие вопросы по тегам