资讯专栏INFORMATION COLUMN

React 事件冒泡

vpants / 817人阅读

摘要:有些情况下,就需要通过阻止事件冒泡来实现预期的交互效果。下面是几个简单的比如有如下的代码当我们点击时,控制台输出结果这两个事件都是合成事件,在点击时,两个事件会依次冒泡到由统一的事件监听器处理。这也说明了,合成事件的只能阻止合成事件的冒泡。

在React中,我们可以在创建element的时候,传入事件和处理函数,这些事件会被做为合成事件来处理,当然,有些时候,我们也需要定义原生事件,比如给document绑定事件。有些情况下,就需要通过阻止事件冒泡来实现预期的交互效果。下面是几个简单的demo

Demo

比如有如下的代码:

import React from "react"
class Demo1 extends React.Component{
    onClickInner(e){
        console.log("inner div")
    }
    onClickOuter(e){
        console.log("outer div")
    }
    render(){
        return 
inner div
} }

当我们点击 inner div时,控制台输出结果:

inner div
outer div

这两个事件都是合成事件,在点击时,两个事件会依次冒泡到document,由统一的事件监听器处理。如果希望阻止onClickOuter 触发,可以在onClickInner内调用e.stopPropagation()。需要注意的是,这里的e是合成事件实例,调用stopPropagation 也只能阻止合成事件的冒泡。

假如我们将onClickOuter 通过原生事件来绑定:

class App extends React.Component {
    onClickInner(e) {
        e.stopPropagation();
        console.log("inner div");
    }
    onClickOuter(e) {
        console.log("outer div");
    }
    componentDidMount() {
        this.outer.onclick = this.onClickOuter;// 通过DOM 0级绑定
    }
    render() {
        return (
            
(this.outer = ref)}>
123
); } }

虽然在onClickInner内调用了 e.stopPropagation, 但是原生事件还是会通过冒泡来触发,而且会先于onClickInner, 控制台输出:

outer div
inner div

这是因为onClickInner合成事件被触发的时候,说明点击事件已经通过冒泡传递到了document,在这个过程中,便会经过外层的div,进而触发该原生事件。这也说明了,合成事件的stopPropagation只能阻止合成事件的冒泡。即使我们在这里通过e.nativeEvent获取到原生事件并调用stopPropagation,也无济于事,因为上面已经说了,在该合成事件被触发的时候,已经冒泡到了document.
那么我们该通过什么方式来阻止原生事件onClickOuter被触发呢:
既然在onClickInner处理不了,只能在onClickOuter内处理了:

onClickOuter(e) {// 这里e是原生事件
   if(e.target && e.target.id === "inner"){
       return ;
   }
   console.log("outer div");
}

如果我们将原生事件绑定在了document上:

class App extends React.Component {
    constructor(props) {
        super(props);
        // this.bindDocument();
    }
    onClickInner(e) {
        console.log("inner div");
    }
    componentDidMount() {
        this.bindDocument();
    }
    bindDocument() {
        document.addEventListener("click", function(e) {
            console.log("document");
        });
    }
    render() {
        return (
            
123
); } }

上面代码中,在组件挂载完毕后,再给document绑定click事件,这时候,React合成事件已经注册完成,当点击时,document上的click事件会依据绑定顺序的先后依次执行,所以控制台会输出:

inner div
document

如果希望阻止后绑定的事件触发,可以在onClickInner内调用stopImmediatePropagation

如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果其中某个监听函数执行了 event.stopImmediatePropagation() 方法,则当前元素剩下的监听函数将不会被执行。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109310.html

相关文章

  • 浅析React事件系统(二)

    摘要:因为阻止事件冒泡的行为只能用于合成事件中,没法阻止原生事件的冒泡。同时的创建和冒泡是在原生事件冒泡到最顶层的之后的。浅析之事件系统一 上篇文章中,我们谈到了React事件系统的实现方式,和在React中使用原生事件的方法,那么这篇文章我们来继续分析下,看看React中合成事件和原生事件混用的各种情况。 上一个例子 在上篇文章中,我们举了个例子。为了防止大家不记得,我们来看看那个例子的代...

    villainhr 评论0 收藏0
  • 窥探react事件

    摘要:解决问题为了解决上述问题,先来了解下的事件,事件是合成事件,为原生事件的一个子集,仅仅是进行了一个跨浏览器的封装。参考本文部分参考自事件初探 写在前面 本文源于本人在学习react过程中遇到的一个问题;本文内容为本人的一些的理解,如有不对的地方,还请大家指出来。本文是讲react的事件,不是介绍其api,而是猜想一下react合成事件的实现方式 遇到的问题 class EventTes...

    刘厚水 评论0 收藏0
  • 结合源码彻底理解 react事件机制原理 04 - 事件执行

    摘要:文章涉及到的源码是基于版本,虽然不是最新版本但是也不会影响我们对事件机制的整体把握和理解。总结本文主要是从整体流程上介绍了下事件触发的过程。 showImg(https://segmentfault.com/img/bVbtvI3?w=1048&h=550); 前言 这是 react 事件机制的第四节-事件执行,一起研究下在这个过程中主要经过了哪些关键步骤,本文也是react 事件机制...

    marser 评论0 收藏0
  • React深入】React事件机制

    摘要:给注册原生事件回调为统一的事件分发机制。根据元素唯一标识和事件类型从中取出回调函数返回带有合成事件参数的回调函数总流程将上面的四个流程串联起来。可见,回调函数是直接调用调用的,并没有指定调用的组件,所以不进行手动绑定的情况下直接获取到的是。 关于React事件的疑问 1.为什么要手动绑定this 2.React事件和原生事件有什么区别 3.React事件和原生事件的执行顺序,可以混...

    philadelphia 评论0 收藏0
  • 《深入react技术栈》学习笔记(三)漫谈React

    摘要:前言接下来让我们进入新的章节漫谈。正文一事件系统的事件系统事件系统符合标准,不存在任何兼容性问题,并且与原生的浏览器事件一样有同样的接口。所有的事件都自动绑定到最外层。组织事件冒泡的行为只适用于合成系统中,且没办法阻止原生事件冒泡。 前言 接下来让我们进入新的章节:漫谈React。本篇文章主要讲React事件系统和表单操作。 正文 一:事件系统 1.react的事件系统react事件系...

    isLishude 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<