深入了解React中的合成事件
1 事件三個(gè)階段 捕獲、目標(biāo)、處理 (具體百度,后面有空補(bǔ)全)
2 示例
import React from "react"; class Test extends React.Component { parentRef; childRef; constructor(props) { super(props); this.parentRef = React.createRef(); this.childRef = React.createRef(); } componentDidMount() { document.addEventListener( "click", () => { console.log(`document原生事件捕獲`); }, true ); document.addEventListener("click", () => { console.log(`document原生事件冒泡`); }); this.parentRef.current.addEventListener( "click", () => { console.log(`父元素原生事件捕獲`); }, true ); this.parentRef.current.addEventListener("click", () => { console.log(`父元素原生事件冒泡`); }); this.childRef.current.addEventListener( "click", () => { console.log(`子元素原生事件捕獲`); }, true ); this.childRef.current.addEventListener("click", () => { console.log(`子元素原生事件冒泡`); }); } handleParentBubble = () => { console.log(`父元素React事件冒泡`); }; handleChildBubble = (e) => { console.log(`子元素React事件冒泡`); }; handleParentCapture = () => { console.log(`父元素React事件捕獲`); }; handleChileCapture = () => { console.log(`子元素React事件捕獲`); }; render() { return ( <div ref={this.parentRef} onClick={this.handleParentBubble} onClickCapture={this.handleParentCapture} > <div ref={this.childRef} onClick={this.handleChildBubble} onClickCapture={this.handleChileCapture} > 事件處理測(cè)試 </div> </div> ); } } export default Test;
執(zhí)行順序
只留子元素修改代碼
import React from "react"; class Test extends React.Component { parentRef; childRef; constructor(props) { super(props); this.parentRef = React.createRef(); this.childRef = React.createRef(); } componentDidMount() { document.addEventListener( "click", () => { console.log(`document原生事件捕獲`); }, true ); document.addEventListener("click", () => { console.log(`document原生事件冒泡`); }); // this.parentRef.current.addEventListener( // "click", // () => { // console.log(`父元素原生事件捕獲`); // }, // true // ); // this.parentRef.current.addEventListener("click", () => { // console.log(`父元素原生事件冒泡`); // }); this.childRef.current.addEventListener( "click", () => { console.log(`子元素原生事件捕獲`); }, true ); this.childRef.current.addEventListener("click", () => { console.log(`子元素原生事件冒泡`); }); } // handleParentBubble = () => { // console.log(`父元素React事件冒泡`); // }; handleChildBubble = (e) => { console.log(`子元素React事件冒泡`); }; // handleParentCapture = () => { // console.log(`父元素React事件捕獲`); // }; handleChileCapture = () => { console.log(`子元素React事件捕獲`); }; render() { return ( <div ref={this.childRef} onClick={this.handleChildBubble} onClickCapture={this.handleChileCapture} > 事件處理測(cè)試 </div> ); return ( <div ref={this.parentRef} onClick={this.handleParentBubble} onClickCapture={this.handleParentCapture} > <div ref={this.childRef} onClick={this.handleChildBubble} onClickCapture={this.handleChileCapture} > 事件處理測(cè)試 </div> </div> ); } } export default Test;
document原生事件捕獲--》子元素React事件捕獲--》子元素原生事件捕獲--》子元素原生事件冒泡--》子元素React事件冒泡--》document原生事件冒泡
從這個(gè)執(zhí)行順序來(lái)看,react事件捕獲執(zhí)行比原生事件捕獲早,但是原生事件冒泡執(zhí)行比react事件冒泡快。
所有的react捕獲事件執(zhí)行完畢之后才會(huì)去執(zhí)行原生的捕獲事件(document原生事件捕獲最先執(zhí)行)
3 子元素阻止react事件冒泡
e.stopPropagation();
import React from "react"; class Test extends React.Component { parentRef; childRef; constructor(props) { super(props); this.parentRef = React.createRef(); this.childRef = React.createRef(); } componentDidMount() { document.addEventListener( "click", () => { console.log(`document原生事件捕獲`); }, true ); document.addEventListener("click", () => { console.log(`document原生事件冒泡`); }); this.parentRef.current.addEventListener( "click", () => { console.log(`父元素原生事件捕獲`); }, true ); this.parentRef.current.addEventListener("click", () => { console.log(`父元素原生事件冒泡`); }); this.childRef.current.addEventListener( "click", () => { console.log(`子元素原生事件捕獲`); }, true ); this.childRef.current.addEventListener("click", () => { console.log(`子元素原生事件冒泡`); }); } handleParentBubble = () => { console.log(`父元素React事件冒泡`); }; handleChildBubble = (e) => { e.stopPropagation(); console.log(`子元素React事件冒泡`); }; handleParentCapture = () => { console.log(`父元素React事件捕獲`); }; handleChileCapture = () => { console.log(`子元素React事件捕獲`); }; render() { return ( <div ref={this.parentRef} onClick={this.handleParentBubble} onClickCapture={this.handleParentCapture} > <div ref={this.childRef} onClick={this.handleChildBubble} onClickCapture={this.handleChileCapture} > 事件處理測(cè)試 </div> </div> ); } } export default Test;
執(zhí)行順序
e.stopPropagation()只能阻止react合成事件的冒泡和document原生事件冒泡,并不能阻止自己和父元素原生事件的冒泡。
e.nativeEvent.stopImmediatePropagation()只能阻止document原生事件冒泡。
e.preventDefault()和不執(zhí)行一樣
e.nativeEvent.stopPropagation()只能阻止document原生事件冒泡。
如果我們?cè)谧釉脑暿录锩孀柚姑芭?,都阻止了?/p>
import React from "react"; class Test extends React.Component { parentRef; childRef; constructor(props) { super(props); this.parentRef = React.createRef(); this.childRef = React.createRef(); } componentDidMount() { document.addEventListener( "click", () => { console.log(`document原生事件捕獲`); }, true ); document.addEventListener("click", () => { console.log(`document原生事件冒泡`); }); this.parentRef.current.addEventListener( "click", () => { console.log(`父元素原生事件捕獲`); }, true ); this.parentRef.current.addEventListener("click", () => { console.log(`父元素原生事件冒泡`); }); this.childRef.current.addEventListener( "click", () => { console.log(`子元素原生事件捕獲`); }, true ); this.childRef.current.addEventListener("click", (e) => { e.stopPropagation(); console.log(`子元素原生事件冒泡`); }); } handleParentBubble = () => { console.log(`父元素React事件冒泡`); }; handleChildBubble = (e) => { console.log(`子元素React事件冒泡`); }; handleParentCapture = () => { console.log(`父元素React事件捕獲`); }; handleChileCapture = () => { console.log(`子元素React事件捕獲`); }; render() { return ( <div ref={this.parentRef} onClick={this.handleParentBubble} onClickCapture={this.handleParentCapture} > <div ref={this.childRef} onClick={this.handleChildBubble} onClickCapture={this.handleChileCapture} > 事件處理測(cè)試 </div> </div> ); } } export default Test;
執(zhí)行順序
在子元素的原聲事件里面,阻止了所有的冒泡。同時(shí)也阻止了react事件。
在父元素原生事件中阻止冒泡
import React from "react"; class Test extends React.Component { parentRef; childRef; constructor(props) { super(props); this.parentRef = React.createRef(); this.childRef = React.createRef(); } componentDidMount() { document.addEventListener( "click", () => { console.log(`document原生事件捕獲`); }, true ); document.addEventListener("click", () => { console.log(`document原生事件冒泡`); }); this.parentRef.current.addEventListener( "click", () => { console.log(`父元素原生事件捕獲`); }, true ); this.parentRef.current.addEventListener("click", (e) => { e.stopPropagation(); console.log(`父元素原生事件冒泡`); }); this.childRef.current.addEventListener( "click", () => { console.log(`子元素原生事件捕獲`); }, true ); this.childRef.current.addEventListener("click", (e) => { console.log(`子元素原生事件冒泡`); }); } handleParentBubble = () => { console.log(`父元素React事件冒泡`); }; handleChildBubble = (e) => { console.log(`子元素React事件冒泡`); }; handleParentCapture = () => { console.log(`父元素React事件捕獲`); }; handleChileCapture = () => { console.log(`子元素React事件捕獲`); }; render() { return ( <div ref={this.parentRef} onClick={this.handleParentBubble} onClickCapture={this.handleParentCapture} > <div ref={this.childRef} onClick={this.handleChildBubble} onClickCapture={this.handleChileCapture} > 事件處理測(cè)試 </div> </div> ); } } export default Test;
執(zhí)行順序
父元素原生事件中阻止冒泡阻止了react事件
阻止document原生事件的冒泡并不會(huì)阻止了react事件
document.addEventListener("click", (e) => { e.stopPropagation(); console.log(`document原生事件冒泡`); });
結(jié)論
react捕獲事件快于原生捕獲事件的執(zhí)行
react冒泡事件慢于原生冒泡事件的執(zhí)行
原生冒泡事件會(huì)阻止react事件。
以上就是深入了解React中的合成事件的詳細(xì)內(nèi)容,更多關(guān)于React合成事件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React Native中導(dǎo)航組件react-navigation跨tab路由處理詳解
這篇文章主要給大家介紹了關(guān)于React Native中導(dǎo)航組件react-navigation跨tab路由處理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10react中的useContext具體實(shí)現(xiàn)
useContext是React提供的一個(gè)鉤子函數(shù),用于在函數(shù)組件中訪問(wèn)和使用Context,useContext的實(shí)現(xiàn)原理涉及React內(nèi)部的機(jī)制,本文給大家介紹react中的useContext具體實(shí)現(xiàn),感興趣的朋友一起看看吧2023-11-11全棧輕量級(jí)搭配之Remix Prisma Sqlite使用分析
這篇文章主要為大家介紹了全棧輕量級(jí)搭配之Remix Prisma Sqlite使用示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05React Hooks 實(shí)現(xiàn)和由來(lái)以及解決的問(wèn)題詳解
這篇文章主要介紹了React Hooks 實(shí)現(xiàn)和由來(lái)以及解決的問(wèn)題詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01React配置多個(gè)代理實(shí)現(xiàn)數(shù)據(jù)請(qǐng)求返回問(wèn)題
這篇文章主要介紹了React之配置多個(gè)代理實(shí)現(xiàn)數(shù)據(jù)請(qǐng)求返回問(wèn)題,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08useEffect?返回函數(shù)執(zhí)行過(guò)程源碼解析
這篇文章主要為大家介紹了useEffect?返回函數(shù)執(zhí)行過(guò)程源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04react-navigation 如何判斷用戶是否登錄跳轉(zhuǎn)到登錄頁(yè)的方法
本篇文章主要介紹了react-navigation 如何判斷用戶是否登錄跳轉(zhuǎn)到登錄頁(yè)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12