Освоение пузыря событий
Предположим, что у нас есть структура HTML, такая как
<div id="container">
<div id="nested">
<span id="someElement"></span>
</div>
</div>
... и наша цель состоит в том, чтобы прослушиватель событий на #container
только! Таким образом, мы связываем прослушиватель (код jQuery)
$("#container").on('click', function(event) {
alert("container was clicked");
});
Это работает, конечно, но моя проблема с этим подходом заключается в том, что, поскольку события обычно пузырятся, этот слушатель также срабатывает, если мы на самом деле нажимаем #nested
или #someElement
. Мое текущее решение только обрабатывает клик, когда щелчком #container
является сравнение this
с event.target
$("#container").on('click', function(event) {
if(this === event.target) {
alert("container was clicked");
}
});
Мой вопрос: Это считается "лучшей практикой"? Есть ли лучший способ с jQuery выполнить один и тот же результат "из коробки"?
Пример в действии: http://jsfiddle.net/FKX7p/
Ответы
Ответ 1
Альтернативный способ предотвращения событий от пузырьков - использовать event.stopPropagation();
$("#container").on('click', function(event) {
alert("container was clicked");
})
.children().on('click', function(event) {
event.stopPropagation();
});
Я думаю, что преимущество использования этого подхода в том, что если вы хотите присоединить другое событие к вложенному div, вы можете просто использовать
$("#nested").on('click', function(event) {
event.stopPropagation();
// some action
});
$("#container").on('click', function(event) {
alert("container was clicked");
});
Ответ 2
Альтернативное решение:
$("#container").click(function(){
alert("container was clicked");
}).children().click(function(e) {
return false;
});
Но ваше решение лучше. jsfiddle.net/FKX7p/2/ (с возвратом false) ИЛИ jsfiddle.net/FKX7p/3/ (с использованием stopPropagation)
Я предпочитаю использовать return в вашем примере (код становится легче читать):
if(this !== event.target) return;
Ответ 3
Я не уверен, какой из них работает быстрее, но имеет смысл, что следующий код будет лучше:
$("#container").click(function (e) {
if (e.target.id && e.target.id !== "container") return false;
});