Разве возвращение false не должно препятствовать пузырям jQuery on ()? - PullRequest
1 голос
/ 27 декабря 2011

Согласно jQuery docs

Возвращение false из обработчика событий автоматически вызовет event.stopPropagation () и event.preventDefault ().Ложное значение также может быть передано для обработчика как сокращение для функции () {return false;}.Итак, $ ("a.disabled"). On ("click", false);присоединяет обработчик событий ко всем ссылкам с классом «отключен», что предотвращает их отслеживание при щелчке, а также предотвращает всплывающее событие.

Поэтому при создании события щелчка:

$('#sidebar').on("click", ".toggle", function() {
    $(this).parents("p").next("ul").toggle(400);
    return false;
});

Я ожидаю, что щелчок не будет зарегистрирован, поскольку у него не будет возможности распространяться от .toggle до #sidebar

Единственное объяснение, которое я придумаю, состоит в том, что еслиэто могло произойти, это сделало бы функцию on() довольно бессмысленной, поэтому, возможно, в этом случае ее обойдут?

Каким правилам следует on() в отношении пузырей?

Ответы [ 3 ]

3 голосов
/ 27 декабря 2011

Для того, чтобы on() работал, событие click должно всплывать до вызывающего элемента, в данном случае #sidebar. on() затем смотрит на цель щелчка, чтобы определить, является ли она .toggle, и запускает функцию соответственно.

Вы можете передать событие в ваш обработчик и добавить

event.stopImmediatePropagation ()

для предотвращения запуска других связанных обработчиков.

3 голосов
/ 27 декабря 2011

Фактически, обработчик присоединен к элементу #sidebar, а не к элементам .toggle.

Так что, когда вы нажимаете на внутренний элемент, событие всплывает, пока не достигнет "#sidebar"и тогда выполняется только обработчик.Возврат false в обработчике, затем остановит дальнейшее распространение.


В документации для .on () это упоминается в примере:

* 1012В дополнение к их способности обрабатывать события на дочерних элементах, которые еще не созданы, еще одним преимуществом делегированных событий является их возможность значительно снизить накладные расходы, когда необходимо отслеживать многие элементы.В таблице данных с 1000 строк в своем теле, этот пример присоединяет обработчик к 1000 элементам:
$("#dataTable tbody tr").on("click", function(event){
    alert($(this).text());
});

Подход с делегированными событиями присоединяет обработчик событий только к одному элементу,tbody, и событие должно всплыть только на один уровень (от нажатой tr до tbody):

$("#dataTable tbody").on("click", "tr", function(event){
    alert($(this).text());
});
1 голос
/ 27 декабря 2011

Событие click в вашем примере прикреплено к #sidebar, и если вы вернете false из обработчика, оно не будет распространяться дальше по дереву DOM.

Вот пример скрипки: http://jsfiddle.net/QymkW/

Это одна из причин недавнего изменения синтаксиса для делегирования события. С использованием синтаксиса .live() можно подумать, что событие было присоединено к элементу, который вы передаете в цепочке, но это всегда было document. Это сбивало с толку с точки зрения распространения.

Используя синтаксис .on(), вы теперь рисуете лучшую картину того, что на самом деле происходит. Событие присоединяется к переданному элементу, и затем вы можете добавить второй аргумент, если хотите делегировать события от потомков. Таким образом, распространение «должно» произойти между делегированными потомками и элементом для делегирования, чтобы работать, но вы все равно можете предотвратить образование пузырьков от элемента, который прикрепил событие (в вашем случае #sidebar)

...