详解React事件机制

一、了解DOM事件流

事件流分为3个阶段

1. 事件捕获阶段:例如点击button,会先捕获body,  然后父元素div,button

2. 处于目标阶段:在button节点上触发

3. 事件冒泡阶段:事件从button冒泡到body-document
 

<body>
 <div>
  <button onclick="handleclick()"></button>
 </div>
</body>

任何事件都是按照次顺序,可以选择在捕获阶段还是冒泡阶段绑定事件处理机制。

element.addEventListener(event, function, flag)

flag为 true,则在捕获阶段绑定;flag为false,则在冒泡阶段绑定事件
 

二、阻止冒泡

IE: window.event.cancelBubble = true;
W3C :event.stopPropagation()

三、事件代理

   又称事件委托,将原本需要绑定在子元素上的事件绑定到父元素身上,让父元素监听,运用 事件冒泡的原理,可以节约内存,减少事件注册,React合成事件使用此方式

四、React事件机制

    合成事件:是跨浏览器原生事件的一个包装器,将不同浏览器的行为根据W3C规范合并为一个API,为了确保事件在不同浏览器中显示一致的属性 。

class TestComponent extends React.Component{
   constructor(props){
     super(props)
     this.state = {
       username: 'cache'
     }
     this.parentRef = React.createRef()
     this.childRef = React.createRef()
   }
   componentDidMount(){
     this.parentRef.current.addEventListener('click', ()=>{
       console.1og(“父元素原生事件捕获”)
     }, true)

     this.parentRef.current.addEventListener('click', ()=>{
       console.1og(“父元素原生事件冒泡”)
     }, false)
     this.childRef.current.addEventListener('click', ()=>{
       console.1og(“子元素原生事件捕获”)
     }, true)

     this.childRef.current.addEventListener('click', ()=>{
       console.1og(“子元素原生事件冒泡”)
     }, false)
     document.addEventListener('click', ()=>{
       console.1og(“document原生事件捕获”)
     }, true)

     document.addEventListener('click', ()=>{
       console.1og(“document原生事件冒泡”)
     }, false)
   }
   parentBubble =()=>{
     console.log('父元素React冒泡事件')
   }
   panentCapture =()=>{
     console.log('父元素React捕获事件')
   }
   childBubble =()=>{
     console.log('子元素React冒泡事件')
   }
   childCapture =()=>{
     console.log('子元素React捕获事件')
   }
   render(){
     return <div ref={this.parentRef} onClick={this.parentBubble} onClickCapture={this.panentCapture}>
      <button ref={this.childRef} onClick={this.childBubble} onClickCapture={this.childCapture}>Test</button>
    </div>
   }

}

以上执行顺序:

document原生事件捕获;

父元素React捕获事件;

子元素React捕获事件;

父元素原生事件捕获;

子元素原生事件捕获;

子元素原生事件冒泡;

父元素原生事件冒泡;

子元素React冒泡事件;

父元素React冒泡事件;

document原生事件冒泡;

document原生事件捕获;

为什么先捕获React事件?

   因为react事件是统一代理到#root或者document上,react应用一进去先注册,注册的早捕获的就早,所以会比原生事件先捕获到。

如果在某个阶段阻止事件传播,后面的事件都不走了?

是的 ,每个事件执行都遵循事件流顺序 ,一但阻止,后续都不执行。

阻止合成事件也会阻止原生事件吗?

是的。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值