javascript - 事件捕获问题?
高洛峰
高洛峰 2017-04-10 15:23:57
[JavaScript讨论组]

代码链接
这是来自《javascript权威指南》17-2的代码,不过我把以下的第三个参数全部修改成了false(原文是true)。

document.addEventListener("mousemove", moveHandler, false);
document.addEventListener("mouseup", upHandler, false);

document.removeEventListener("mouseup", upHandler, false);
document.removeEventListener("mousemove", moveHandler, false);

看似并没有出现问题。

事件传播的三个阶段的原理我已经了解了,我并不是不知道这个,我是不知道在这个case把true改为false会有什么区别?

我阐述一下我的理解,拿moveHandler来说:
当鼠标移动时,先进行事件捕获,从window开始捕获,然而并没有相应的capturing event handler,然后把事件传到下一层document,由于document注册了capturing event handler,所以调用了该hanler,随后执行到e.stopPropagation时停止事件的后续传播。

如果换成false的话:首先跳过capture阶段(因为没有注册任何相关的capturing event handler),然后事件传递到target,但是target上没有注册跟mousemove有关的handler,因此跳过此阶段,进行bubble阶段,于是事件传呀传呀传到了document,被其注册的bubble阶段的handler所接收到,然后调用该handler,执行相应代码。

这两种我觉得从结果上来讲没有任何区别,如果非要说区别的话,我觉得只是用true速度快一些,因为在捕获阶段就停止了事件的后续传播。

但是原文中写到:

值得注意的是mousemove和mouseup处理程序注册为捕获事件处理程序。这是因为用户可能移动鼠标比其后的文档元素更快,如果这种情况发生,某些mousemove事件会发生在原始目标元素之外。没有捕获,这些事件将无法分派正确的处理程序。

的确,某些mousemove事件会发生在原始目标元素之外,这会导致事件的target未必一直是我们所拖动的那个元素,但这样会产生任何问题吗?我们用到的与事件对象相关的代码只有这些:

elementToDrag.style.left = (e.clientX + scroll.x - deltaX) + "px";
elementToDrag.style.top = (e.clientY + scroll.y - deltaY) + "px";

也就是只用到了事件对象的坐标属性,与事件本身是谁没有关系。
不过还有一句我比较困惑:

if (e.stopPropagation) e.stopPropagation()

这个就跟事件本身是谁有关了,然而我不知道这会产生什么不良的影响?

不知道以上的理解有没有问题,求证。

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(2)
天蓬老师

“DOM2级事件”规定的事件流包括三个阶段:
- 事件捕获
- 处于目标阶段
- 事件冒泡

首先发送事件捕获, 然后实际目标接受到事件,最后是事件冒泡。

“DOM2级事件”规范明确要求捕获阶段不涉及事件目标,但现代浏览器都会在捕获阶段触发事件目标对象上的事件。所以有两个机会在目标对象上操作事件。

addEventListener()removeEventListener()的第三个参数是布尔值,true表示在捕获阶段调用事件处理程序,false则是在冒泡阶段调用事件处理程序。

p.s.《JavaScript高级程序设计》第13章详细介绍了事件。

天蓬老师

如果将 useCapture 设置为 true,则侦听器只在捕获阶段处理事件,而不在目标或冒泡阶段处理事件。 如果useCapture 为 false,则侦听器只在目标或冒泡阶段处理事件。 要在所有三个阶段都侦听事件,请调用两次 addEventListener,一次将 useCapture 设置为 true,第二次再将useCapture 设置为 false。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号