Подтвердить что ты не робот

Распространение событий паузы Javascript

Мне нужно иметь возможность цепочки событий кликов и временно приостанавливать распространение событий между ними.

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

clickAction2 = ->
  #Pause event propagation
  somehow.pauseEventPropegationRightHere()

  #Go and handle the dialogs, user input, JS requests
  goDoSomething().thenDoCallback( ->
     #User is now authenticated completely.
     somehow.continueEventPropegationAsIfNothingHappened()
  )

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

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

Это относится к директивам AngularJS, но решение не нужно полагаться на него.

Есть аналогичный вопрос, но ни один из ответов не является удовлетворительным: Как продолжить распространение событий после отмены?.

Edit:

Мне нужен более чистый способ вызвать e.stopImmediatePropagation(), а затем продолжить с этой точки. На данный момент лучшим вариантом является ручной ввод "частных" данных jQuery [1] и вызов функций вручную.

  • $._data( $(element)[0], 'events' ).click[].handler()
4b9b3361

Ответ 1

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

Проблема (если я правильно понимаю) заключается в том, что вам нужен способ предотвращения инициирования дочернего элемента событием, если родительский элемент инициировал одно и то же событие по существу в одно и то же время. В то время как e.stopImmediatePropagation() предотвращает пузырьки событий, эффективно останавливая любые родительские элементы при запуске события. Я полагаю, что решение использует setTimeout() с нулевой миллисекундной задержкой для выполнения требуемой функции, и если событие срабатывания когда-либо повторяется, когда используется setTimeout(), используйте clearTimeout(), чтобы остановить предыдущее событие. Лучший способ продемонстрировать этот подход - создать родительский и дочерний элемент и посмотреть событие mouseleave.

Вот JS/jQuery:

var timerActive = false;
$('#div1, #div2').mouseleave(function(e) {
    var trigger = $(this).attr('id'); // for monitoring which element triggered the event
    if (timerActive) {
        clearTimeout(announce); // stops the previous event from performing the function
    }
    window.announce = setTimeout(function() {
        alert('mouse exited'+trigger); // trigger could be use in an if/else to perform unique tasks
        timerActive = false;
    },0);
    timerActive = true;
});

Вот демон JSFiddle: http://jsfiddle.net/XsLWE/

Поскольку события запускаются последовательно от дочернего к родительскому, очистка каждого предыдущего таймаута эффективно ожидает, чтобы последний или самый верхний элемент вызывал событие. В этот момент вы можете использовать инструкцию IF/ELSE для выполнения желаемых задач. Или выполните одну функцию, а затем завершите обратный вызов.

В демонстрации эффект заключается в том, что на левом и нижнем краях элементов div каждому элементу div разрешено инициировать событие индивидуально. Однако на верхнем и правом краях div2 единственным элементом, разрешенным для запуска события, является div1.

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

Ответ 2

Попробуйте что-нибудь вроде

elem.on('event',function(e) {
    e.stopPropagation();

    goDoSomething(function(){
        elem.parent().trigger(e);
    });
});

goDoSomething() может выполнить вызов AJAX или что-то еще асинхронное, а затем по какой-либо причине вызвать обратный вызов для продолжения распространения событий