Firefox не может установить фокус на определенные элементы DOM, используя JavaScript - PullRequest
0 голосов
/ 28 марта 2019

При разработке веб-приложения я понял, что, если установить contenteditable="true" для элемента label, почти все браузеры, включая IE 10 и 11, могут установить фокус на элемент label, кроме Firefox.

Исследуя больше, я обнаружил, что это поведение относится только к определенным элементам, включая элемент label, в то время как оно отлично работает для других, таких как h4, p и span.

Я создал JS Bin для всех, кто хочет попробовать это.

Может кто-нибудь объяснить, является ли это ожидаемым поведением, которое игнорируют другие браузеры, или это ошибка в Firefox?

PS: Мои спецификации Windows 10 x64 и Firefox 66.0.1 x64 .

function focusId(id) {
  document.getElementById(id).focus();
}
<label id="label" contenteditable="true" tabindex="0">Label</label>
<h4 id="h4" contenteditable="true" tabindex="0">H4</h4>
<p id="p" contenteditable="true" tabindex="0">Paragraph</p>
<span id="span" contenteditable="true" tabindex="0">Span</span>
<hr />
<button onclick="focusId('label')">Label</button>
<button onclick="focusId('h4')">H4</button>
<button onclick="focusId('p')">Paragraph</button>
<button onclick="focusId('span')">span</button>

1 Ответ

0 голосов
/ 28 марта 2019

TL; DR : использование элемента <label> и атрибута contenteditable не запрещено в спецификации HTML, но в зависимости от браузера приведет к непредвиденному поведению.


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

Давайте забудем contenteditableпока просто подумайте, как работает элемент <label>.

Как указано в спецификации HTML :

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

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

Так что, если бы мы вставили помечаемый элемент внутри <label>,затем вызов .focus() на метке должен привести к тому, что метка будет сфокусирована, но не к метке.

См. этот пример в JS Bin .Как в Firefox, так и в Chrome, результатом будет то, что сфокусированный элемент будет входом, а не меткой.

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

Кнопка ввода (если атрибут типа не находится в скрытом состоянии) Индикатор хода выполнения выбора выберите textarea

В связи с этим, ипоскольку в представленном вами примере нет никакого помечаемого содержимого, связанного с <label>, ожидаемый результат должен быть бездействующим.

Но теперь появляется атрибут contenteditable, который делает элемент фокусируемым через tab и щелчок указателя.

Это полностью противоречит идее перенаправления <label> событий на цель, поскольку требуется как сохранить, так и передать эти события.

Правильный вопрос: Как браузер должен обрабатывать оба этих поведения?

Что ж, это будет неутешительно, но я полагаю, это зависит от реализации этого крайнего случая для каждого браузера.И я даже не могу сказать, правильно ли один из них делает это.С моей точки зрения, Firefox кажется более строгим в отношении спецификации элемента метки HTML, тогда как Chromium позволяет более свободно использовать взаимодействия.

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


Поэтому я рекомендую не использовать <label> для того, кем вы являетесьпытаясь достичь.

Поскольку у вас, похоже, нет какого-либо элемента формы, использование <span> сделает эту работу и будет семантически лучше.Ярлык, на котором ничего не обозначено, - это просто текст.
Или даже <textarea>, если вы можете себе это позволить.

Если вам действительно нужен ярлык текст, который фокусируется на элементе формы, но все еще редактируемый, спросите себя, что вам нужно отдавать приоритет.Когда вы активируете указатель, вы хотите, чтобы элемент формы был сфокусирован или редактировать текст?<button> в стиле простого текста может помочь, и вам решать, какие события вызывают фокусировку другого элемента формы.Не то чтобы у вас возникли серьезные проблемы с доступностью, и я бы не рекомендовал это делать.

...