// Example A
$("#delegate").on("click", function(event) {
// executes on click on any descendant of #delegate or self (not a delegate at all)
// 'this' is #delegate
});
// Example B
$("#delegate").on("click", "#outer", function(event) {
// executes on click on any descendant of #outer or self
// 'this' is #outer or #inner (depends on the actual click)
});
$("#delegate").on("click", "#inner", function(event) {
// executes on click on any descendant of #inner or self (nothing happens when clicking #outer)
// 'this' is #inner
});
// Example C (now it's getting weird)
$("#delegate").on("click", "div", function(event) {
// executes twice, when clicking #inner, because the event passes #outer when bubbling up
// one time 'this' is #inner, and the other time 'this' is #outer
// stopPropagation() // actually prevents the second execution
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="delegate">
<div id="outer">
outer
<div id="inner">
inner
</div>
</div>
</div>
Как логически объяснить такое поведение?
Существует ровно одно событие клика, которое начинается #inner
, всплывает через #outer
и, наконец, достигает #delegate
.
Событие перехватывается (точно) один раз обработчиком #delegate
. Обработчик проверяет, содержит ли история события какие-либо элементы div.
Если это применимо, функция обратного вызова должна быть вызвана один раз. Это то, что я ожидал. «Одно событие, один обработчик, одно условие, один обратный вызов».
Это становится еще более сумасшедшим, если вы посмотрите на поведение stopPropagation()
. На самом деле вы можете избежать второго выполнения, хотя событие уже достигло #delegate
. stopPropagation(
здесь не должно работать.
Какая «магия» делается при реализации логики делегирования? Разделяются ли каким-либо образом всплытие событий и программный поток?
Пожалуйста, не публикуйте «практические советы» в первую очередь («Используйте вместо этого xyz!»). Я хотел бы понять, почему код работает именно так.
click
во втором и третьем вызове. - person Barmar   schedule 11.09.2015div
? - person Barmar   schedule 11.09.2015<div>
в#delegate
, и присоединение события click ко всем div внутри него, следовательно, вызовет 2 события при нажатии#inner
. Конечно, использование stopPropagation предотвратит всплытие с#inner
на#outer
. - person Alex   schedule 11.09.2015