Фокусировка и размытие событий jQuery, не пузырящихся

Со следующей структурой html:

<div>
<form><span><input></span></form>
</div>
<p>

и следующий код jquery:

$('form').on("focus", function(event) {
    $("p").append("focus no delegation<br>");
})

Почему событие фокуса никогда не достигает моего обработчика событий? Связывание события с параметром селектора отлично работает:

$('form').on("focus", "input", function(event) {
    $("p").append("focus delegation<br>");
})

Событие следующего фрагмента работает так, что фокусное событие действительно пузырь...

$('form').on("focus", "span", function(event) {
    $("p").append("focus delegation<br>");
})

Обе формы работают с событиями кликов и изменений:

$('form').on("click", function(event) {
    $("p").append("click no delegation<br>");
})
$('form').on("click", "input", function(event) {
    $("p").append("click delegation<br>");
})

Единственное замечание, которое я узнал о пузырьке фокуса, относится к более старым версиям jQuery, которые я не использую. Смотрите здесь в действии здесь

изменить 1

Ну, это сбивает с толку... Согласно jQuery focus doc:

Событие фокуса не пузырится в Internet Explorer. Поэтому сценарии, которые полагаются на делегирование событий с событием фокуса, не будут работать последовательно в браузерах. Начиная с версии 1.4.2, jQuery работает вокруг этого ограничения, сопоставляя фокус с событием focusin в своих методах делегирования событий .live() и .delegate().

И согласно jQuery focusin doc:

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

Это слишком поздно для меня или противоречит другому?

Ответ 1

Да, похоже, что документы jQuery вводят в заблуждение. Я считаю, что документация на focus пренебрегла упоминанием о том, что это было для элементов, которые не участвуют в пользовательском вводе (@Ohgodwhy перечислил их выше в ваших комментариях вопроса).

Я предполагаю, что это имеет какое-то отношение к браузеру, чтобы уловить курсор во входном элементе с focus, чтобы он мог принимать ввод с клавиатуры. Другими словами, если jQuery разрешил ему пузыриться, тогда вам никогда не будет дано ввести поле ввода.

В любом случае вы никогда не получите форму, чтобы принять событие focus, если вы сначала не положили на него tabindex: http://jsfiddle.net/qxLqP/, но если поле ввода основано сначала на фокусе, оно никогда не будет пузыриться. По умолчанию элемент form не имеет tabindex, и вы не можете установить фокус на то, что не имеет tabindex.

Я бы просто принял решение @Ohgodwhy с использованием focusin, а затем позвольте команде jQuery узнать о своей запутанной документации.

Ответ 2

Как указывал Ohgodwhy, использование focusin вместо фокуса действительно работает.

Однако я не могу понять, как следующий код может работать, если событие "focus" не пузырится:

$('form').on("focus", "span", function(event) {
    $("p").append("focus delegation<br>");
})

Если дочерний элемент формы формы принимает событие "фокус", это означает, что событие разбухало от входа до диапазона. Даже это работает!

$('div').on("focus", "form", function(event) {
    $("p").append("focus delegation<br>");
})

Итак... использование "focusin" действительно устраняет проблему, но я не полностью удовлетворен этим обходным решением. Если кто-нибудь получит лучший ответ, я с радостью приму это.

Ответ 3

JQuery имеет функцию перекрестного браузера, которая обслуживает делегацию фокуса.

Chrome, сафари и опера поддерживают событие под названием "DOMFocusIn", которое фактически делегирует.

IE поддерживает событие "focusin" для делегирования фокуса.

Firefox поддерживает "фокус" только для фазы фаз, а не для пузырьков.

jQuery сделал кросс-браузерное событие, которое является "фокусом", которое фактически делегирует.

Надеюсь, это ответит на все ваши сомнения.