摘要:有些情況下,就需要通過阻止事件冒泡來實(shí)現(xiàn)預(yù)期的交互效果。下面是幾個(gè)簡單的比如有如下的代碼當(dāng)我們點(diǎn)擊時(shí),控制臺(tái)輸出結(jié)果這兩個(gè)事件都是合成事件,在點(diǎn)擊時(shí),兩個(gè)事件會(huì)依次冒泡到由統(tǒng)一的事件監(jiān)聽器處理。這也說明了,合成事件的只能阻止合成事件的冒泡。
在React中,我們可以在創(chuàng)建element的時(shí)候,傳入事件和處理函數(shù),這些事件會(huì)被做為合成事件來處理,當(dāng)然,有些時(shí)候,我們也需要定義原生事件,比如給document綁定事件。有些情況下,就需要通過阻止事件冒泡來實(shí)現(xiàn)預(yù)期的交互效果。下面是幾個(gè)簡單的demo
Demo比如有如下的代碼:
import React from "react" class Demo1 extends React.Component{ onClickInner(e){ console.log("inner div") } onClickOuter(e){ console.log("outer div") } render(){ return} }inner div
當(dāng)我們點(diǎn)擊 inner div時(shí),控制臺(tái)輸出結(jié)果:
inner div outer div
這兩個(gè)事件都是合成事件,在點(diǎn)擊時(shí),兩個(gè)事件會(huì)依次冒泡到document,由統(tǒng)一的事件監(jiān)聽器處理。如果希望阻止onClickOuter 觸發(fā),可以在onClickInner內(nèi)調(diào)用e.stopPropagation()。需要注意的是,這里的e是合成事件實(shí)例,調(diào)用stopPropagation 也只能阻止合成事件的冒泡。
假如我們將onClickOuter 通過原生事件來綁定:
class App extends React.Component { onClickInner(e) { e.stopPropagation(); console.log("inner div"); } onClickOuter(e) { console.log("outer div"); } componentDidMount() { this.outer.onclick = this.onClickOuter;// 通過DOM 0級(jí)綁定 } render() { return ((this.outer = ref)}>); } }123
雖然在onClickInner內(nèi)調(diào)用了 e.stopPropagation, 但是原生事件還是會(huì)通過冒泡來觸發(fā),而且會(huì)先于onClickInner, 控制臺(tái)輸出:
outer div inner div
這是因?yàn)?b>onClickInner合成事件被觸發(fā)的時(shí)候,說明點(diǎn)擊事件已經(jīng)通過冒泡傳遞到了document,在這個(gè)過程中,便會(huì)經(jīng)過外層的div,進(jìn)而觸發(fā)該原生事件。這也說明了,合成事件的stopPropagation只能阻止合成事件的冒泡。即使我們?cè)谶@里通過e.nativeEvent獲取到原生事件并調(diào)用stopPropagation,也無濟(jì)于事,因?yàn)樯厦嬉呀?jīng)說了,在該合成事件被觸發(fā)的時(shí)候,已經(jīng)冒泡到了document.
那么我們?cè)撏ㄟ^什么方式來阻止原生事件onClickOuter被觸發(fā)呢:
既然在onClickInner處理不了,只能在onClickOuter內(nèi)處理了:
onClickOuter(e) {// 這里e是原生事件 if(e.target && e.target.id === "inner"){ return ; } console.log("outer div"); }
如果我們將原生事件綁定在了document上:
class App extends React.Component { constructor(props) { super(props); // this.bindDocument(); } onClickInner(e) { console.log("inner div"); } componentDidMount() { this.bindDocument(); } bindDocument() { document.addEventListener("click", function(e) { console.log("document"); }); } render() { return (123); } }
上面代碼中,在組件掛載完畢后,再給document綁定click事件,這時(shí)候,React合成事件已經(jīng)注冊(cè)完成,當(dāng)點(diǎn)擊時(shí),document上的click事件會(huì)依據(jù)綁定順序的先后依次執(zhí)行,所以控制臺(tái)會(huì)輸出:
inner div document
如果希望阻止后綁定的事件觸發(fā),可以在onClickInner內(nèi)調(diào)用stopImmediatePropagation:
如果有多個(gè)相同類型事件的事件監(jiān)聽函數(shù)綁定到同一個(gè)元素,當(dāng)該類型的事件觸發(fā)時(shí),它們會(huì)按照被添加的順序執(zhí)行。如果其中某個(gè)監(jiān)聽函數(shù)執(zhí)行了 event.stopImmediatePropagation() 方法,則當(dāng)前元素剩下的監(jiān)聽函數(shù)將不會(huì)被執(zhí)行。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/109310.html
摘要:因?yàn)樽柚故录芭莸男袨橹荒苡糜诤铣墒录校瑳]法阻止原生事件的冒泡。同時(shí)的創(chuàng)建和冒泡是在原生事件冒泡到最頂層的之后的。淺析之事件系統(tǒng)一 上篇文章中,我們談到了React事件系統(tǒng)的實(shí)現(xiàn)方式,和在React中使用原生事件的方法,那么這篇文章我們來繼續(xù)分析下,看看React中合成事件和原生事件混用的各種情況。 上一個(gè)例子 在上篇文章中,我們舉了個(gè)例子。為了防止大家不記得,我們來看看那個(gè)例子的代...
摘要:文章涉及到的源碼是基于版本,雖然不是最新版本但是也不會(huì)影響我們對(duì)事件機(jī)制的整體把握和理解。總結(jié)本文主要是從整體流程上介紹了下事件觸發(fā)的過程。 showImg(https://segmentfault.com/img/bVbtvI3?w=1048&h=550); 前言 這是 react 事件機(jī)制的第四節(jié)-事件執(zhí)行,一起研究下在這個(gè)過程中主要經(jīng)過了哪些關(guān)鍵步驟,本文也是react 事件機(jī)制...
摘要:給注冊(cè)原生事件回調(diào)為統(tǒng)一的事件分發(fā)機(jī)制。根據(jù)元素唯一標(biāo)識(shí)和事件類型從中取出回調(diào)函數(shù)返回帶有合成事件參數(shù)的回調(diào)函數(shù)總流程將上面的四個(gè)流程串聯(lián)起來。可見,回調(diào)函數(shù)是直接調(diào)用調(diào)用的,并沒有指定調(diào)用的組件,所以不進(jìn)行手動(dòng)綁定的情況下直接獲取到的是。 關(guān)于React事件的疑問 1.為什么要手動(dòng)綁定this 2.React事件和原生事件有什么區(qū)別 3.React事件和原生事件的執(zhí)行順序,可以混...
摘要:前言接下來讓我們進(jìn)入新的章節(jié)漫談。正文一事件系統(tǒng)的事件系統(tǒng)事件系統(tǒng)符合標(biāo)準(zhǔn),不存在任何兼容性問題,并且與原生的瀏覽器事件一樣有同樣的接口。所有的事件都自動(dòng)綁定到最外層。組織事件冒泡的行為只適用于合成系統(tǒng)中,且沒辦法阻止原生事件冒泡。 前言 接下來讓我們進(jìn)入新的章節(jié):漫談React。本篇文章主要講React事件系統(tǒng)和表單操作。 正文 一:事件系統(tǒng) 1.react的事件系統(tǒng)react事件系...
閱讀 2993·2021-10-19 11:46
閱讀 987·2021-08-03 14:03
閱讀 2946·2021-06-11 18:08
閱讀 2914·2019-08-29 13:52
閱讀 2764·2019-08-29 12:49
閱讀 490·2019-08-26 13:56
閱讀 932·2019-08-26 13:41
閱讀 855·2019-08-26 13:35