jsfiddle : https://jsfiddle.net/leiming/5e6rtgwd/
class Sample extends React.Component {
onInputFocus(event) {
console.log('react input focus')
}
onSpanFocus(event) {
console.log('react span focus')
// event.stopPropagation()
}
render() {
return ( <span onFocus = {this.onSpanFocus}>
react input: <input type="text"
onFocus = {this.onInputFocus} />
</span> )
}
}
ReactDOM.render( < Sample / > ,
document.getElementById('container')
);
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
<div>
<span onfocus="(function(){console.log('normal span')})()">
normal input:<input type="text" onfocus="(function(){console.log('normal input focus')})()">
</span>
</div>
jsfiddle : https://jsfiddle.net/leiming/5e6rtgwd/
Using React, onFocus
in <input/>
will bubble which is not same as usual HTML5.
Could anyone give me the refer doc why focus bubbles with React?
focus
events do not bubble, so you're correct that the behavior in React differs from that of the DOM. The DOM has a focusin
event that does bubble; here's a demonstration:
<div>
<span onfocus="(function(){console.log('span focus')})()">
onfocus: <input type="text"
onfocus="(function(){console.log('input focus')})()">
</span>
</div>
<div>
<span onfocusin="(function(){console.log('span focusin')})()">
onfocusin: <input type="text"
onfocusin="(function(){console.log('input focusin')})()">
</span>
</div>
Looking through the React source code, it seems this was intentional; the code checks for whether or not the browser supports the focus
event with capturing, and implements it via the focus
event with ReactEventListener.trapCapturedEvent
instead of ReactEventListener.trapBubbledEvent
. This is necessary because React implements its synthetic event system using event delegation, and so needs to use either capturing or bubbling for all its event handling. The article linked to in the comment explains how this works:
The problem is that these events do not bubble up. A focus or blur event on a link fires only on the link itself, and not on any ancestor element of the link.
This is an ancient rule. A few events, most notably focus, blur, and change, do not bubble up the document tree. The exact reasons for this have been lost in the mist of history, but part of the cause is that these events just don't make sense on some elements. The user cannot focus on or change a random paragraph in any way, and therefore these events are just not available on these HTML elements. In addition, they do not bubble up.
...
Except when you use event capturing.
...
One of the most curious conclusions of my event research is that when you define event handlers in the capturing phase the browser executes any and all event handlers set on ancestors of the event target whether the given event makes sense on these elements or not.
It seems pretty likely that the React team decided to simply make the event always bubble (which, to be honest, is what I expected from the DOM spec as well until I read your question). The browser implementations don't seem to be consistent; one issue comment mentions that focus
events bubble in Firefox, but I was not able to reproduce that on a recent version. However, using an onfocusin
attribute or using addEventListener("focusin", ...)
also didn't work in FF. So it's possible that this was simply an attempt at normalizing the events across browsers.
All that said, it does seem there is perhaps a bug where the .bubbles
property on a SyntheticFocusEvent
is false
instead of true
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With