Пример из реального мира, где захват событий необходим / предпочтителен?
addEventListener
Метод DOM поддерживает третий необязательный логический параметр (useCapture), чтобы указать, должна ли функция использовать всплывающее или перехват событий в качестве метода распространения. В этой статье отличия хорошо показаны (нажмите на примеры и посмотрите код).
Из других вопросов, касающихся SO и постов в блоге, я пришел к выводу, что всплытие событий было предпочтительнее в основном потому, что IE8- не поддерживал его.
Предположим, мне требуется только поддержка IE9+, в какой ситуации захват событий будет необходим или предпочтителен по сравнению с всплывающими событиями? Другими словами, в какой ситуации было бы лучше, чтобы события сначала выполнялись для самых внешних элементов, а затем для самых внутренних элементов? Я ищу простой пример из реальной жизни, чтобы продемонстрировать использование захвата событий...
1 ответ
Захват событий раньше был единственным вариантом за пределами браузера Internet Explorer:
Одно из главных отличий двух важных браузеров того времени заключалось в том, как они обрабатывали события. Microsoft работала с фазой пузырьков - это означает, что событие сначала передает родительские элементы, а затем переходит к целевому элементу. NETscape сделал это совершенно другим способом - и сначала событие попало в целевой элемент, а затем переместилось вверх по всей DOM, ударив по родительским узлам, - захватило. В первые дни это доставляло разработчикам много хлопот, и W3C, наконец, определил подход, при котором оба вида работают и могут использоваться по собственному желанию.
Захват событий полезен при делегировании событий, когда пузыри не поддерживаются. Например:
Некоторые события, такие как фокусировка, не всплывают, но могут быть зафиксированы. Встроенный обработчик на целевом элементе срабатывает перед обработчиками захвата для целевого элемента.
Многие вновь определенные события в веб-платформе (такие как медиа-события) не всплывают, что является проблемой для сред, таких как Ember, которые полагаются на делегирование событий. Однако API захвата, который был добавлен в IE9, корректно вызывается для всех событий и не требует уровня нормализации. Поддержка API захвата не только позволит нам удалить зависимость jQuery, но и позволит правильно обрабатывать эти не пузырьковые события. Это позволит вам использовать такие события, как воспроизведение в ваших компонентах, без необходимости вручную настраивать прослушиватели событий.
У пользовательских событий и пузырей есть следующие проблемы:
В настоящее время Ember использует jQuery для обработки событий, что связано с несколькими затратами:
jQuery silently changes inline handlers to bubble handlers.
This changes expected invocation order
This can cause automated tests to fail
Events triggered via jQuery.trigger trigger handlers in a different order than events triggered by a user.
This changes expected invocation order
This leads to difficult to reason about and debug aberrations in behavior
This often causes automated tests to fail
Events must flow down and bubble back up through the entire DOM before being detected by the Ember application, and then must undergo an expensive delegation process that is effectively re-bubbling to find the right handler.
Handlers attached directly within components or by non-ember plugins take precedent over handlers attached by Ember, whether this was desired or not.
This causes component handlers to have far-reaching side-effects
This leads to difficult to reason about and debug aberrations in behavior
This often causes automated tests to fail
Медиапроигрыватель focus=>play поток событий preprocess/postprocess будет простым вариантом использования.
Механизм фазы захвата делает его идеальным для подготовки или предотвращения поведения, которое позже будет применено делегированием события во время фазы пузырьков. И вот как мы собираемся использовать его здесь - чтобы инициализировать сортируемую информацию в ответ на щелчок мышью, но непосредственно перед тем, как событие начинает пузыриться, и другие обработчики имеют возможность с этим справиться.
Чтобы использовать захват, мы должны спуститься к металлу. Методы событий jQuery работают только для всплытия и не позволяют нам вступить в фазу захвата. Обработчик захвата выглядит так:
document.addEventListener("mousedown", function(event) {
if ($(event.target).closest(".sortable_handle").length) {
$("article.todolist, section.todolists").sortable();
}
}, true);
Рекомендации