2.在React中,每个事件处理回调函数都会自动绑定到组件实例(使用ES6语法创建的例外);
与浏览器事件处理稍微有不同的是,React中的事件处理程序所接收的事件参数是被称为“合成事件(SyntheticEvent)”的实例。
stopPropagation(),preventDefault()
等,并且
这些接口是跨浏览器兼容的。使用JSX,在React中绑定事件:
<button onClick={this.onClick}>
单击触发react事件
</button>
- boolean bubbles
- boolean cancelable
- DOMEventTarget currentTarget
- boolean defaultPrevented
- number eventPhase
- boolean isTrusted
- DOMEvent nativeEvent
- void preventDefault()
- boolean isDefaultPrevented()
- void stopPropagation()
- boolean isPropagationStopped()
- DOMEventTarget target
- number timeStamp
- string type
onCopy onCut onPaste
onKeyDown onKeyPress onKeyUp
onFocus onBlur
onChange onInput onSubmit
onClick onContextMenu onDoubleClick
onDrag onDragEnd onDragEnter onDragExit
onDragLeave onDragOver onDragStart onDrop
onMouseDown onMouseEnter onMouseLeave
onMouseMove onMouseOut onMouseOver onMouseUp
onSelect
onTouchCancel onTouchEnd onTouchMove onTouchStart
onScroll
onWheel
onLoad onError
onAnimationStart onAnimationEnd onAnimationIteration
onToggle
componentDidMount阶段/ref的函数执行阶段进行绑定操作,在componentWillUnmount
阶段进行解绑操作以避免内存泄漏。import React,{Component} from 'react';
import ReactDOM from 'react-dom'
class ReactEvent extends Component {
componentDidMount() {
//获取当前真实DOM元素
const thisDOM = ReactDOM.findDOMNode(this);
thisDOM.addEventListener('click',this.onDOMClick,false);
}
componentWillUnmount() {
//卸载时解绑事件,防止内存泄漏
const thisDOM = ReactDOM.findDOMNode(this);
thisDOM.removeEventListener('click',this.removeDOMClick);
}
onDOMClick(e){
console.log(e)
}
render(){
return(
<div>
单击原始事件触发
</div>
)
}
}
export default ReactEvent
import React,{Component} from 'react';
import ReactDOM from 'react-dom'
class ReactEvent extends Component {
constructor(props){
super(props)
this.state = {
value: ''
}
this.onReactClick = this.onReactClick.bind(this)
}
componentDidMount() {
//获取当前真实DOM元素
const thisDOM = ReactDOM.findDOMNode(this);
thisDOM.addEventListener('click',this.onDOMClick,false);
}
componentWillUnmount() {
//卸载时解绑事件,防止内存泄漏
const thisDOM = ReactDOM.findDOMNode(this);
thisDOM.removeEventListener('click',this.removeDOMClick);
}
onDOMClick(e){
console.log("原生事件绑定事件触发")
}
onReactClick(e){
console.log("React合成事件绑定事件触发")
}
render(){
return(
<div onClick={this.onReactClick}>
单击事件触发
</div>
)
}
}
export default ReactEvent
1. 原生事件绑定事件触发
2. 合成事件绑定事件触发
onDOMClick(e){
e.stopPropagation()
console.log("原生事件绑定事件触发")
}
- 原生事件绑定事件触发再测试个复杂的例子
import React,{Component} from 'react';
import ReactDOM from 'react-dom'
class ReactEvent extends Component {
constructor(props){
super(props)
this.state = {
value: ''
}
this.onReactClick = this.onReactClick.bind(this)
this.onReactChildClick = this.onReactChildClick.bind(this)
}
componentDidMount() {
//获取当前真实DOM元素
const thisDOM = ReactDOM.findDOMNode(this);
thisDOM.addEventListener('click',this.onDOMClick,false);
//获取子元素并绑定事件
const thisDOMChild = thisDOM.querySelector(".child");
thisDOMChild.addEventListener('click',this.onDOMChildClick,false);
}
onDOMClick(e){
console.log("父组件原生事件绑定事件触发")
}
onReactClick(e){
console.log("父组件React合成事件绑定事件触发")
}
onDOMChildClick(e){
e.stopPropagation()
console.log("子元素原生事件绑定事件触发")
}
onReactChildClick(e){
console.log("子元素React合成事件绑定事件触发")
}
render(){
return(
<div onClick={this.onReactClick}>
父元素单击事件触发
<button className="child" onClick={this.onReactChildClick}>子元素单击事件触发</button>
</div>
)
}
}
export default ReactEvent
1. 在子元素原生事件程序中阻止事件传播,则打印出:
- 子元素原生事件绑定事件触发;
2. 在父元素元素事件程序中阻止事件传播,则打印出:
- 子元素原生事件绑定事件触发
- 父组件原生事件绑定事件触发
3. 在子元素React合成事件onClick中阻止事件传播,则打印出:
- 子元素原生事件绑定事件触发
- 父组件原生事件绑定事件触发
- 子元素React合成事件绑定事件触发
4. 在父元素React合成事件onClick中阻止事件传播,则打印出:
- 子元素原生事件绑定事件触发
- 父组件原生事件绑定事件触发
- 子元素React合成事件绑定事件触发
- 父组件React合成事件绑定事件触发可以看到若不阻止事件传播每次(单击子元素)事件触发流程是:
Document->子元素(原生事件触发)->父元素(原生事件)->回到Document->React子元素合成事件监听器触发 ->React父元素合成事件监听器触发
其实,React合成事件封装的stopPropagtion函数在调用时给自己加了个isPropagationStopped的标记位来确定后续监听器是否执行。