Недавно я столкнулся с проблемой в React при кросс-браузерном тестировании. Проблема возникает при вызове focus()
для элемента, содержащего автоматически генерируемые теги <span>
.
Упрощенный компонент
Мой компонент, <Button/>
, является абстракцией нормальной <button>
с дополнительными функциями. Вот упрощенная версия:
Вывод:
<Button value="Button"/>
является:
<button><span>Button</span></button>
Из-за того, что React автоматически обертывает плавающие текстовые узлы в промежутке, поэтому он может назначать data-reactid
, текст внутри <button>
заключен в теги <span>
.
Кнопка имеет метод onClick()
для вызова event.target.focus()
элемента.
Проблема
В Chrome/Firefox нажатие кнопки устанавливает фокус на кнопку. В Safari нажатие кнопки не всегда устанавливает фокус на кнопку. Вместо этого <body>
получает фокус.
После нескольких часов вождения я обнаружил, что кнопка получает фокус только при нажатии за пределами автоматически генерируемых тегов <span>
(синие области кнопки ниже). Щелчок в тегах <span>
созданных React (черные области кнопки ниже), заставит <body>
получить фокус.
Опять же, это происходит только в Safari.
В Chrome/Firefox нажатие любой из областей приводит к тому, что <button>
получает фокус.
Здесь CodePen, содержащий полный пример, шаги для воспроизведения:
<span>
). Вы заметите, что focused
элемент (с использованием document.activeElement
), скорее всего, является <body>
.<button>
. Вы заметите, что focused
элементом является <button>
.Вопрос
Есть ли предпочтительный метод для согласования поведения между браузерами? Или это не связано с React и просто разница в том, как Safari/Chrome/Firefox обрабатывают focus()
?
Одно из возможных решений: set pointer-events: none;
на внутреннем элементе <span>
. Это позволит кликам на <span>
распространяться до <button>
. Однако это кажется хакером.
Можете ли вы просто использовать ссылку?
ака
something(event){
this.refs.button.focus()
}
render(){
// stuff
return (
<button ref="button" onClick={this.something}>
{some text here that will make a span element around it}
</button>
);
}
<span>
приводит к фокусировке<button>
. Однако, если я нажимаю<button>
затем перемещаюсь по<span>
это вызывает некоторую нестабильность CSS. Мне нужно оставитьpointer-events: none
к сожалению. Тем не менее, это решает проблему.