Вопрос по jquery, event-binding, event-bubbling, javascript, jquery-events – Прямое или делегированное - jQuery .on ()

146

Я пытаюсь понять эту конкретную разницу междунепосредственный а такжеделегироваться обработчики событий, использующиеJQuery.на() метод, В частности, последнее предложение в этом пункте:

Когдаselector предоставляется, обработчик события называетсяделегироваться, Обработчик вызывается не тогда, когда событие происходит непосредственно в связанном элементе, а только для потомков (внутренних элементов), которые соответствуют селектору. jQuery переносит событие от цели события до элемента, к которому прикреплен обработчик (т. е. от самого внутреннего к внешнему элементу), и запускает обработчик для любых элементов на этом пути, соответствующих селектору.

Что означает «запускает обработчик для любых элементов»? я сделалтестовая страница экспериментировать с концепцией. Но обе следующие конструкции ведут к одинаковому поведению:

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

или же,

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

Может быть, кто-то мог бы обратиться к другому примеру, чтобы прояснить этот момент? Благодарю.

Для всех заинтересованных:jsperf.com/jquery-fn-on-delegate-vs-direct dgo
«Тестовая страница», на которую вы ссылаетесь, не работает. Jaime Montoya
@KevinWheeler Я прокомментировал вашу скрипку ниже, ноВотпо сути, он настроен неправильно (вы привязываетесь к родительскому элементу, а делегирование предназначено для дочерних элементов). Чтобы ответить на ваш вопрос, моё, это означает, что делегированный обработчик будет соответствовать новым добавленным элементам, а тот, что без делегирования, не будет. Преимущество делегирования заключается в том, что в браузере подключается меньше событий, что снижает потребление памяти приложением, однако компромисс заключается в том, что он увеличивает время обработки клика (минимально). Если вы делаете игру, не делегируйте. vipero07

Ваш Ответ

5   ответов
2

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

Связанный относится к тому, что осталось от.on.Выбранный относится ко 2-му аргументу.on().

Делегирование не работает как .find (), выбирая подмножество связанных элементов. Селектор применяется только к строгим дочерним элементам.

$("span.green").on("click", ...

сильно отличается от

$("span").on("click", ".green", ...

В частности, чтобы получить преимущества, на которые намекает @ N3dst4 с «элементами, которые будут созданы в будущем», связанный элемент должен бытьпостоянный родитель, Тогда выбранные дети могут приходить и уходить.

РЕДАКТИРОВАТЬ

Контрольный список того, почему делегированы.on не работает

Хитрые причины, почему$('.bound').on('event', '.selected', some_function) может не работать:

Связанный элемент непостоянный, Было создано после звонка.on()Выбранный элемент не является правильнымребенок связанного элемента. Это тот же элемент.Выбранный элемент заблокированкипение события в связанный элемент путем вызова.stopPropagation().

(Опуская менее хитрые причины, такие как селектор с ошибкой.)

355

Случай 1 (прямой):

$("div#target span..on("click", function() {...});

== Эй! Я хочу, чтобы каждый span.green внутри div # target прослушивался: когда вы нажмете, сделайте X.

Дело 2 (делегировано):

$("div#target").on("click", "span.green", function() {...});

== Эй, div # target! Когда щелкнет любой из ваших дочерних элементов, которые являются «span.green», выполните X с ними.

Другими словами...

В случае 1 каждому из этих промежутков были даны индивидуальные инструкции. Если создаются новые пролеты, они не услышат инструкции и не будут реагировать на клики. Каждый промежутокпрямая ответственность для своих собственных событий.

В случае 2 инструкция была дана только контейнеру; он отвечает за уведомление о кликахот имени его дочерние элементы. Работа по ловле событий быладелегироваться, Это также означает, что инструкция будет выполняться для дочерних элементов, которые будут созданы в будущем.

Могу ли я дать этот ответ +10? И затем -1, потому что теперь я должен переписать кучу своих утверждений .on () теперь, когда я понимаю, как сделать это правильно. Anthony
.on () - это API общего назначения, который может обрабатывать любые события, включая несколько разных событий (вы можете поместить несколько имен событий в эту первую строку.) .click () - это просто сокращение для этой первой формы. N3dst4
Так почему жеon() разрешить два аргумента, когда это в значительной степени будет таким же, как при использованииclick()? nipponese
+1 для говорящих элементов DOM. Paul Brewczynski
Это отличное объяснение, и оно внесло ясность в проблему, которую я давно отказался понять. Спасибо! dgo
4

мы можем предположить, что все дочерние элементы находятся внутри тела, поэтому нам нужно использовать только это:

$('body').on('click', '.element', function(){
    alert('It works!')
});

Работает с прямым или делегированным событием.

В современных браузерах$('body').on() делегация из.element должен вести себя точно так же, как роднойdocument.body.addEventHandler() сif (Event.target.className.matches(/\belement\b/)) в обратном вызове. Это может быть немного медленнее в jquery из-за$.proxy накладные расходы, но не цитируйте меня об этом. cowbert
jquery не советует использовать body, так как он медленнее, потому что скрипт должен будет искать всех потомков внутри тела, чего в большинстве случаев должно быть много. Лучше (быстрее) использовать промежуточный родительский контейнер элемента. mikesoft
Jquery удалил живой метод, который делал то же, что вы показали. Это слабая производительность и не должна использоваться. Maciej Sikora
1

ваю чистый js, но он имеет то же значение для jquery, которое только инкапсулирует его.

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

Для получения дополнительной информации и полного сравнения -http://maciejsikora.com/standard-events-vs-event-delegation/

Использование всегда делегированных обработчиков, что, на мой взгляд, в настоящее время очень модно, является неправильным способом, многие программисты используют его потому, что «его следует использовать», но правда в том, что прямые обработчики событий лучше в некоторых ситуациях, и выбор, какой метод использовать, должен поддерживаться. знанием различий.

если подключено много обработчиков событий (например, каждой строки таблицы), часто лучше по производительности использовать один делегированный обработчик для контейнера вместо присоединения многих прямых обработчиков. Это видно из того факта, что количество обработчиков событий само по себе является метрикой профилирования. cowbert
0

$("div#target span.green").on(), привязывает обработчик щелчка непосредственно к диапазону (ам), который соответствует селектору в момент выполнения кода. Это означает, что если другие диапазоны будут добавлены позже (или их класс будет изменен, чтобы соответствовать), они пропустили и не будут иметь обработчик щелчка. Это также означает, что если позже вы удалите «зеленый» класс из одного из диапазонов, его обработчик кликов будет продолжать работать - jQuery не отслеживает, как был назначен обработчик, и проверяет, совпадает ли селектор.

Второй способ,$("div#target").on(), привязывает обработчик кликов к совпадающим элементам (ам), которые совпадают (опять же, с теми, которые совпадают в данный момент), но когда щелчок происходит где-то в элементе div, функция обработчика запускается, только если щелчок произошел не только в div, но в дочернем элементе, соответствующем селектору во втором параметре.on()"span.green". Сделано таким образом, не имеет значения, когда были созданы эти дочерние промежутки, щелчок по ним все равно запускает обработчик.

Так что для страницы, которая динамически не добавляет и не изменяет свое содержимое, вы не заметите разницы между этими двумя методами. Если вы динамически добавляете дополнительные дочерние элементы, второй синтаксис означает, что вам не нужно беспокоиться о назначении им обработчиков кликов, потому что вы уже сделали это один раз для родительского элемента.

Похожие вопросы