美文网首页
合成事件

合成事件

作者: 糖糖不加糖_ | 来源:发表于2023-02-09 14:47 被阅读0次

    合成事件

    合成事件是浏览器原生事件的跨浏览器的包装器,他拥有浏览器的所有原生事件相同接口,与原生事件不同,是react建造的事件,他的接口不会直接映射到原生事件的接口上(eg:onMouseLeave映射到mouseout),在 React 中,e.nativeEvent 才是原生 DOM 事件的那个 event。

    事件委托
    • 利用事件冒泡机制,将一个元素的响应事件放到另一个元素上(eg: <li>上的点击事件不用每个都是用onClick,直接放到<ul>上即可)
    • 事件流响应机制为:事件捕获阶段 => 目标元素阶段 => 事件冒泡阶段,参见下图 image.png
    • dom2级事件规定捕获阶段不会涉及事件目标,但是在ie9,safari,chrome,firefox和opera9.5及更高版本都会在捕获阶段触发事件对象上的事件,即:有两次机会出发事件操作(另一个发生的机会是在目标元素阶段)

    合成事件影响案例

    需要做一个弹窗打开/关闭 的功能,当点击 button 的时候打开,此时打开的情况下,点击弹窗区域外,就需要关闭。

    // 直接在 button 上注册一个点击事件,同时在 document.body 注册一个点击事件,然后在 弹窗container 里阻止冒泡
    class FuckEvent extends React.PureComponent {
      state = {
        showBox: false
      }
      componentDidMount() {
        document.body.addEventListener('click', this.handleClickBody, false)
      }
      componentWillUnmount() {
        document.body.removeEventListener('click', this.handleClickBody, false)
      }
      handleClickBody = () => {
        this.setState({
          showBox: false
        })
      }
      handleClickButton = () => {
        this.setState({
          showBox: true
        })
      }
    
      render() {
        return (
          <div>
            <button onClick={this.handleClickButton}>点击我显示弹窗</button>
    
            {this.state.showBox && (
              <div onClick={e => e.stopPropagation()}>我是弹窗</div>
            )}
          </div>
        )
      }
    }
    

    实际结果为当前的阻止冒泡不生效,点击弹窗依然会被关闭

    React 合成事件与原生事件执行顺序图

    image.png
    image.png
    • 合成事件执行需要冒泡到document后才会进行触发(16版本及以下),此时在捕获阶段,原生事件已经执行了,所以上述例子中点击弹窗也会直接关闭
    • react中的阻止事件冒泡只能阻止合成事件的冒泡,无法处理原生事件
    • 原生事件阻止冒泡可以阻止合成事件冒泡,因为走不到那一步了(17版本及以上,其实调用的就是绑定在当前节点的原生浏览器事件)

    react 16及之前的版本,事件监听是挂载到document节点上的,17及以上就挂载到dom容器上(root element)

    image.png

    参考文献:

    相关文章

      网友评论

          本文标题:合成事件

          本文链接:https://www.haomeiwen.com/subject/thdzxdtx.html