一场由窗口莫名关闭引起的血案
偶然的一次机会,我把窗口的关闭事件绑在了body上,代码是用react写的。于是,意外发生了。在点击窗口内部内容的时候窗口关闭了,这时候其实在代码中已经阻止冒泡了,绑定事件没有用捕获。于是,就有了下列的探索。
试验一:
这里我不阻止任何事件。

输出:
此时输出很正常,和原生事件一致。先捕获,后冒泡

试验二:

输出:
react中,冒泡的时候,可以冒泡到body层,再执行事件。
原生中,先执行事件,然后再网上冒泡。
由此可以知道,原声中,阻止了,就是阻止了。不会再往上冒泡。但在react中,并不是这样的,react事件必须冒泡到body上才能被阻止,因为事件阻止是写在输出clicked地方的。。


试验三:
我们在点击的上层加个parent。看target是什么。

输出:
其实这里已经可以看到react的事件执行过程了。
document捕获,body捕获,一直到body冒泡,在body冒泡之后再执行事件函数。其实这里可以断定react是把事件代理到了document上。不然不会等到body冒泡完。

试验四:
这次我们看下react的阻止冒泡阻止了什么。

看,子组件的事件被执行之后,父组件已经捕获不到冒泡了。所有的这一切,是在body冒泡之后去做的。

试验五:
我们看看react中这句话做了什么。

输出:
好像,并没有什么乱用。。该输出的都输出了。

为什么呢?这句话的意思是阻止原生事件的冒泡,但是,react真的能阻止吗?当然不能。因为在组件渲染的时候,这个事件就已经绑定在dom标签上了,虽然react在document上代理了冒泡事件处理逻辑,但也仅限于阻止body的冒泡,为什么呢,因为reat合成事件触发的时候,body都冒泡完了。但如果真是这样,为什么这里的document为什么还会输出呢?
试验六:
我们排除一下其它监听的影响。

输出:
哇,果然是被其它监听影响了。

总结一下:
原生事件没什么说的,阻止了就是阻止了。
react不一样,react是合成事件,而且合成事件的执行时间是在body冒泡结束之后。这可以说明,事件是代理到document上。
网友评论