事件干扰之阻止事件冒泡
场景:
在启动3d虚拟仿真时注册一个keydown事件,用来触发3d基本体的复制粘贴操作
遇到的问题:
在这个页面有一个blocky积木块控制面板区域,调起这个面板,同样可以进行复制粘贴操作,而且快捷键一样,这就出现了在复制积木块的时候同时也进行了3d基本体的复制操作,在复制3d基本体同时也进行了复制积木块的操作
解决:
1、运用 document.activeElement 获取当前获得焦点的元素 ,判断是否为积木块区域,如果是,则不进行3d基本体的复制操作
2、在注册3d基本体keydown事件里面执行阻止冒泡操作,避免进行到积木块的复制操作
相关知识点:
区分不同区域的事件处理:
- 使用
closest方法检查当前获得焦点的元素是否位于指定区域(例如#blocklyDiv或#customDiv)。 - 根据事件来源区域执行不同的逻辑。
.stop修饰符:
.stop 是 Vue.js 事件修饰符之一,用于阻止事件传播(即阻止事件冒泡)。当你在 Vue 模板中使用 .stop 修饰符时,相当于在事件处理函数中调用了 event.stopPropagation()。
语法:
1 | <element @event.stop="handler"></element> |
event.stopPropagation()
- 作用:阻止事件冒泡,但不影响当前元素上其他事件处理器的执行。
- 应用场景:当你希望阻止事件继续传播到父级元素,但允许当前元素上的其他事件处理器继续执行时使用。
event.stopImmediatePropagation()
- 作用:立即停止事件传播,并阻止当前元素上任何后续事件处理器的执行。
- 应用场景:当你希望阻止事件传播到父级元素,同时阻止当前元素上的所有其他事件处理器时使用。
区别
**event.stopPropagation()**:- 只阻止事件冒泡到父级元素。
- 当前元素上的其他事件处理器仍然会被执行。
**event.stopImmediatePropagation()**:- 阻止事件冒泡到父级元素。
- 阻止当前元素上任何后续事件处理器的执行。
为什么 event.stopImmediatePropagation() 生效而 event.stopPropagation() 不生效?
如果你的代码中 event.stopPropagation() 不生效,而 event.stopImmediatePropagation() 生效,可能是因为在同一元素上有多个事件处理器,你需要确保阻止所有事件处理器的执行。
示例
假设你有一个父 div 和一个子 div,并且你希望在子 div 上阻止 keydown 事件冒泡,并且不执行其他任何事件处理器:
1 | <div id="app"> |
示例解释
- 父级
**div**:
- 绑定了
keydown事件,触发parentKeydownHandler方法。
- 绑定了
- 子级
**div**:
- 绑定了
keydown事件,触发childKeydownHandler方法。 childKeydownHandler方法中使用event.stopImmediatePropagation()来阻止事件传播并阻止其他事件处理器。
- 绑定了
如果你使用 event.stopPropagation():
- 事件将不会冒泡到父级
div,但当前元素(子div)上的其他事件处理器仍然会被执行。
如果你使用 event.stopImmediatePropagation():
- 事件将不会冒泡到父级
div,并且当前元素(子div)上的其他事件处理器也不会被执行。
结论
- 使用
event.stopPropagation()来阻止事件冒泡,但允许当前元素上的其他事件处理器执行。 - 使用
event.stopImmediatePropagation()来立即阻止事件传播,并且阻止当前元素上的所有其他事件处理器执行。
理解: 如果两个keydown事件都绑定在document上,这个时候就不存在谁是谁父级的关系,只有使用event.stopImmediatePropagation()才生效 。
如果两个 keydown 事件监听器都绑定在 document 上,那么它们之间不存在父子关系。此时,event.stopPropagation() 无法阻止其他同级监听器的执行,因为它仅阻止事件的冒泡或捕获过程,而不是同一阶段的其他监听器的执行。
在这种情况下,如果你希望阻止同级监听器的执行,就需要使用 event.stopImmediatePropagation()。这个方法不仅会阻止事件传播,还会阻止当前目标上后续的事件监听器执行。
示例
假设你有两个 keydown 事件监听器都绑定在 document 上:
1 | <!DOCTYPE html> |
解释
- 两个
**keydown**监听器:都绑定在document上。 - 使用
**event.stopPropagation()**:无法阻止第二个监听器的执行。 - 使用
**event.stopImmediatePropagation()**:可以立即阻止第二个监听器的执行。
结论
**event.stopPropagation()**:只阻止事件在 DOM 树中的传播(冒泡或捕获),但不会阻止当前目标上其他同级监听器的执行。**event.stopImmediatePropagation()**:不仅阻止事件传播,还会阻止当前目标上后续的事件监听器执行。在没有父子关系的情况下,使用event.stopImmediatePropagation()可以确保其他同级事件监听器不会被执行。










