跳到主要内容

操作

2023年11月26日
柏拉文
越努力,越幸运

一、事件冒泡


冒泡阶段: 开发者正常给 React 绑定的事件比如 onClickonChange,默认会在模拟冒泡阶段执行

export default function Index(){
const handleClick=()=>{ console.log('模拟冒泡阶段执行') }
const handleClickCapture = ()=>{ console.log('模拟捕获阶段执行') }
return <div>
<button onClick={ handleClick } onClickCapture={ handleClickCapture } >点击</button>
</div>
}

二、事件捕获


捕获阶段: 如果想要在捕获阶段执行可以将事件后面加上 Capture 后缀,比如 onClickCaptureonChangeCapture

export default function Index(){
const handleClick=()=>{ console.log('模拟冒泡阶段执行') }
const handleClickCapture = ()=>{ console.log('模拟捕获阶段执行') }
return <div>
<button onClick={ handleClick } onClickCapture={ handleClickCapture } >点击</button>
</div>
}

三、阻止冒泡


3.1 阻止合成事件间的冒泡

React中如果想要阻止事件向上冒泡,可以用e.stopPropagation()React 阻止冒泡和原生事件中的写法差不多,但是底层原理完全不同

export default function Index(){
const handleClick=(e)=> {
e.stopPropagation() /* 阻止事件冒泡,handleFatherClick 事件讲不在触发 */
}
const handleFatherClick=()=> console.log('冒泡到父级')
return <div onClick={ handleFatherClick } >
<div onClick={ handleClick } >点击</div>
</div>
}

3.2 *阻止合成事件与最外层 document 上的事件间的冒泡

阻止合成事件与最外层 document 上的事件间的冒泡: e.nativeEvent.stopImmediatePropagation()

3.3 阻止合成事件与除最外层 document 上的原生事件上的冒泡

阻止合成事件与除最外层 document 上的原生事件上的冒泡: 通过判断e.target来避免

document.body.addEventListener('click', e => {   
if (e.target && e.target.matches('div.code')) {
return;
}
this.setState({ active: false, }); });
}

四、阻止默认行为


React阻止默认行为和原生的事件也有一些区别

4.1 原生

原生事件: e.preventDefault()return false 可以用来阻止事件默认行为

4.2 React

React 应用中, 给元素的事件并不是真正的事件处理函数,所以导致 return false 方法在 React 应用中完全失去了作用。React事件逻辑如下:

function dispatchEvent(){ // React 事件真正的执行函数为 dispatchEvent
for(){
……依次处理 React 事件注册的函数 // 即使 React 事件函数中有 return false , 也不会处理
}
}

document.addEventListener('click',dispatchEvent)

e.preventDefault(): 在React应用中,可以用 e.preventDefault() 阻止事件默认行为,这个方法并非是原生事件的 preventDefault ,由于 React 事件源 e 也是独立组建的,所以 preventDefault 也是单独处理的。