无论哪一个做UI层的都会碰到事件传递的一些问题,一些我们可以巧妙的通过特殊组件来解决手势冲突或者传递问题,否则只能硬着头皮解决解决问题了
本篇文章以react为例,其中碰到的主要就是阻止事件向下冒泡
div默认的 onClick 默认不阻止事件自底向上冒(也就是从子节点向父节点冒泡),因此如果祖先节点还有点击事件也会触发,因此,我们就要阻止事件向下冒泡了
1.reactnode 点击事件
函数回调的参数调用 stopPropagation 即可
//使用onClick点击时间
<div
onClick={(e) => {
//父布局点击事件,如果子组件没有阻止冒泡,这里仍然能够响应
}}>
<div
onClick={(e) => {
//阻止事件向下冒泡,如果不想让父布局响应事件的话
e.stopPropagation();
}}
</div>
</div>
2. addEventListener 注册原生事件
开发中可能碰到 addEventListener事件,这类属于注册事件仅仅使用 stopPropagation()是无法阻止他的事件相应的,此时需要使用 nativeEvent.stopImmediatePropagation()来阻止原生事件调用
与此同时如果是混合事件,某个响应时间,其需要屏蔽某些事件冒泡带来的响应,则可以通过 e.target 判断当前方法是否继续响应
userEffect(() => {
//我们注册了一个点击事件,有可能在组件上,有可能在 document 上
document.addEventListener('click', this.onDocumentClick, false);
let element = document.getElementById('my-listener')
element?.addEventListener('click', this.onElementClick, false
}, [])
//document原生事件,通过 nativeEvent.stopImmediatePropagation阻止了react节点冒泡到这里
const onDocumentClick = (e) => {
console.log('handleDocumentClick: ', e);
}
//注册到某个节点的事件,可以规避一些事件冒泡带来的效果
const onElementClick = (e) => {
//采用 target 来判断是否响应,可以判断是否是某一个响应的
if (e.target && e.target === document.querySelector('#sub-sender')) {
return;
}
console.log('handleDocumentClick: ', e);
}
<div
id="my-listener"
onClick={(e) => {
//父布局点击事件,如果子组件没有阻止冒泡,这里仍然能够响应
}}>
<div
id="sub-sender"
onClick={(e) => {
//阻止事件向下冒泡,如果不想让父布局响应事件的话
e.stopPropagation();
// 阻止与原生事件的冒泡
e.nativeEvent.stopImmediatePropagation();
}}
</div>
</div>