jQuery .on ();vs JavaScript .addEventListener (); - PullRequest
36 голосов
/ 25 января 2012

Может кто-нибудь объяснить мне, почему существует разница в порядке выполнения обработчиков событий в зависимости от того, как они были присоединены?В приведенном ниже примере я использую методы .on() и .addEventListener() для обработки определенного события для различных элементов DOM.

jsfiddle : http://jsfiddle.net/etsS2/

Я думал, что в этом конкретном примере порядок, в котором будут выполняться обработчики событий, будет зависеть от event-bubbling - поэтому начиная с исходного события target и продвигаясь к элементу document.

document.getElementById('outer').addEventListener('mouseup', function (event) {
//$('#outer').on('mouseup', function (event) {
    alert('This alert should not show up!');
}, false);

Если я раскомментирую версию on();, все будет работать как положено - есть ли разница в том, как jQuery обрабатывает события, противоречащие обычному JavaScript?

Ответы [ 2 ]

22 голосов
/ 25 января 2012

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

Событие «пузыри» - это процесс, с помощью которого браузер ищет обработчики событий, зарегистрированные у родителей элемента, который был фактическим исходным получателем события.Это работает вверх в дереве DOM.Уровень документа - проверенный уровень последний .Таким образом, ваш обработчик, зарегистрированный с .on(), не будет работать, пока этот уровень не будет достигнут.Между тем, другой обработчик событий на «внешнем» уровне достигается первым, и он выполняется браузером.

Таким образом, то, что return false; в обработчике, зарегистрированном в .on(), в значительной степени бесполезно,как будет звонить на event.stopPropagation().Кроме того, смешивать регистрацию встроенного обработчика событий с работой, которую будет выполнять библиотека, такая как jQuery, возможно, очень плохая идея, если вы не знаете, что делаете.

Был вопрос, заданный почти точнокак этот совсем недавно сегодня.

12 голосов
/ 25 января 2012

Посмотрите на addEventListener версию:

document.getElementById('outer').addEventListener('mouseup', function (event) {
    alert('This alert should not show up!');
}, false);

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

Когда вы переключаетесь на версию jQuery:

$('#outer').on('mouseup', function (event) {
    alert('This alert should not show up!');
}, false);

Я думаю, что то, что происходит, является третьим аргументом, просто переопределяет вашу функцию обработчика событий и заставляет обработчик событий ничего не делать, кроме return false;, что явно не то, что должно происходить.

Из документов jQuery (выделение добавлено):

Функция, выполняемая при срабатывании события. Значение false также допускается как сокращение для функции, которая просто возвращает ложь .

Удалите аргумент false, и версия jQuery также будет работать правильно:

$('#outer').on('mouseup', function (event) {
    alert('This alert should not show up!');
});

Обратите внимание, что alert должен отображаться , поэтому подход addEventListener работает правильно. См. Ответ @ Pointy, почему это так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...