GithubHelp home page GithubHelp logo

Comments (20)

Lx15 avatar Lx15 commented on May 28, 2024 7

@youngwind 作者你好,我又认真的读了你的文章,做了测试,发现是有问题的:

  1. 其实原生事件的执行时间总是先于合成事件,无论合成事件是不是在捕获阶段绑定
  2. 所以上述用例的执行结果: 直接绑定在Child上的事件-》直接绑定在document上的事件-》点击子元素-》点击父元素
  3. 所以你上面图的描述其实是错误的
  4. 结果是对的,但是 e.nativeEvent.stopImmediatePropagation()其实只能在document 上才有用,换成
    document.getElementById('parent')都是不可以的

from blog.

LiuYashion avatar LiuYashion commented on May 28, 2024 3

谢谢作者~

from blog.

acrens avatar acrens commented on May 28, 2024 1

结论:
1、e.stopPropagation 可以用来禁用 React 模拟事件;
2、e.nativeEvent.stopImmediatePropagation 只能用来禁用直接绑定在 document 上的事件;
3、对 2 的补充,试想一下,child 元素通过 React 直接绑定事件会被模拟到 document 上,parent 元素通过原生 addEventListener 绑定,通过冒泡原来应该 parent 先被触发,所以无法在 child 元素内禁用 parent 元素绑定的事件(当然,实际开发中,应该不会去 child 通过 React 绑定事件,而 parent 却不使用 React 绑定事件)。

from blog.

0x457 avatar 0x457 commented on May 28, 2024

谢谢作者~

from blog.

cloudsere avatar cloudsere commented on May 28, 2024

写的太好了!!

from blog.

Lx15 avatar Lx15 commented on May 28, 2024

作者你好,很感谢你的文章,解开了我的疑惑,但是如果是下面的这种情景该怎样解决呢?
image

我想在点击子元素时,只是点击子元素,而不点击父元素,该怎样阻止呢?

from blog.

youngwind avatar youngwind commented on May 28, 2024

这种情况,除非你全部使用 React 绑定或者原生绑定,否则我想不到可阻止的方法。 @Lx15

from blog.

Lx15 avatar Lx15 commented on May 28, 2024

@youngwind 或者 在父元素上用target判断一下,可行不优雅

from blog.

youngwind avatar youngwind commented on May 28, 2024

哈哈哈,角度刁钻,但也确实可行。 @Lx15

from blog.

amnsss avatar amnsss commented on May 28, 2024

大赞!!!

from blog.

vincentdd avatar vincentdd commented on May 28, 2024

感谢作者,同类分析里写的简单易懂的一个

from blog.

Nick930826 avatar Nick930826 commented on May 28, 2024

写得不错

from blog.

someOneJYB avatar someOneJYB commented on May 28, 2024

测试发现document原生绑定事件在合成的事件执行之后执行,原生事件(document元素事件)-》点击子元素-》点击父元素-》直接绑定在document上的事件。链接地址
https://codesandbox.io/s/q33v4vw866

from blog.

someOneJYB avatar someOneJYB commented on May 28, 2024

补充一下在react页面里面打印了一下绑定在document上的click事件,发现第一个就是react绑定的事件,然后才是我在Didmount上绑定的事件

from blog.

yes1am avatar yes1am commented on May 28, 2024

@youngwind 作者你好,我又认真的读了你的文章,做了测试,发现是有问题的:

  1. 其实原生事件的执行时间总是先于合成事件,无论合成事件是不是在捕获阶段绑定
  2. 所以上述用例的执行结果: 直接绑定在Child上的事件-》直接绑定在document上的事件-》点击子元素-》点击父元素
  3. 所以你上面图的描述其实是错误的
  4. 结果是对的,但是 e.nativeEvent.stopImmediatePropagation()其实只能在document 上才有用,换成
    document.getElementById('parent')都是不可以的

@Lx15

根据我的测试结果,和你的结论有点出入,一起讨论下:

  1. 原生事件执行总是先于合成事件?

你说的这种情况只在给 非document,window元素 ` 添加原生事件时成立,当给document添加原生事件时,还取决于添加原生事件的时机:

在render之前添加原生事件,那么原生事件先于合成事件绑定,触发时先执行原生事件。
在render之后比如didMount 中,那么合成事件先于原生事件绑定,触发时先执行合成事件。

  1. 作者的结论是对的。

因为在作者在 didMount 中添加的事件,先执行原生的直接绑定在Child事件,然后根据在 didMount 中添加事件,所以合成事件先于原生事件执行,执行 点击子元素, 阻止冒泡所以 点击父元素不执行。最后会执行原生添加的 直接绑定在Document事件

  1. e.nativeEvent.stopImmediatePropagation()其实只能在document 上才有用?

我测试的结果是,这个api对其它元素也有效。可能我理解错你的意思了?

from blog.

wujiedong avatar wujiedong commented on May 28, 2024

作者你好,很感谢你的文章,解开了我的疑惑,但是如果是下面的这种情景该怎样解决呢?
image

我想在点击子元素时,只是点击子元素,而不点击父元素,该怎样阻止呢?

parent的那个事件使用react中的合成事件,不要写原生事件,然后再子dom的事件中直接e.stopPropagation(),这样事件就不会冒泡到父那边
我试过子是合成事件,父是原生事件,这种方式我没有成功阻止冒泡

from blog.

sanfengliao avatar sanfengliao commented on May 28, 2024

from blog.

jachan-lr avatar jachan-lr commented on May 28, 2024

非常非常非常有用,感谢!!!

from blog.

BigKongfuPanda avatar BigKongfuPanda commented on May 28, 2024

写的很清楚。但是有个地方有问题:
function dispatchEvent(event) { let target = event.target; target.click && target.click(); // 触发点击元素的事件 while (target.parentNode) { // 沿 DOM 向上回溯,遍历父节点,触发其 click 事件 target.parentNode.click && target.parentNode.click(); target = target.parentNode; } }
节点上并没有绑定事件,不存在click函数。具体好像是react会在每个节点上生成一个唯一的id,把id与click事件的函数作为map的数据结构的形式存在一个全局对象中。调用 dispatchEvent的时候,会找到当前节点的id找到click函数。

from blog.

yang1666204 avatar yang1666204 commented on May 28, 2024

太赞了!!!

from blog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.