I recently ran into an issue in React when cross-browser testing. The issue occurs when calling focus()
on an element containing React's auto-generated <span>
tags.
Simplified Component
My component, a <Button/>
, is an abstraction of a normal <button>
with additional features. Here's a simplified version:
The output of:
<Button value="Button"/>
is:
<button><span>Button</span></button>
Due to React's auto-wrapping of floating text nodes in a span so it can assign a data-reactid
, the text within the <button>
is wrapped in <span>
tags.
The button has an onClick()
method to call event.target.focus()
on the element.
The Issue
In Chrome/Firefox clicking the button sets focus on the button. In Safari, clicking the button does not always set focus on the button. Instead the <body>
receives focus.
After several hours of fiddling I discovered the button receives focus only when clicked outside of React's auto-generated <span>
tags (the blue areas of the button below). Clicking within the <span>
tags created by React (the black areas of the button below) will cause the <body>
to gain focus.
Again, this only happens in Safari.
In Chrome/Firefox, clicking either of the areas results in the <button>
gaining focus.
Here's a CodePen containing the full example, the steps to reproduce:
<span>
tag). You'll notice the focused
element (using document.activeElement
) is most likely the <body>
. <button>
tag. You'll notice the focused
element is the <button>
. Question
Is there a preferred method for making the behavior consistent across browsers? Or is this unrelated to React and merely a difference in how Safari/Chrome/Firefox handle focus()
?
One possible solution: set pointer-events: none;
on the inner <span>
element. This would allow clicks on the <span>
to propagate through to the <button>
. This seems hackish however.
Can you just use a ref?
aka
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>
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.