關(guān)于js中e.preventDefault()的具體使用
背景:
同事在項(xiàng)目中遇到的問題,在項(xiàng)目中導(dǎo)入了某一個組件作為根組件之后,發(fā)現(xiàn)原來的子組件中的滾動效果不再生效,因?yàn)槭且苿佣说捻?xiàng)目,所以這里的滾動效果是通過touchmove事件進(jìn)行觸發(fā)的,在對引入的組件進(jìn)行研究后,發(fā)現(xiàn)是在根組件中阻止了touchmove事件的默認(rèn)事件,也就是調(diào)用了e.preventDefault()方法,然后同事們通過阻止冒泡阻止了這個方法的調(diào)用,解決掉了因?yàn)橐虢M件而帶來的問題,但這卻引發(fā)了一連串的有關(guān)于preventDefault()這個方法的思考。
問題:
為什么我在父組件上使用preventDefault(),阻止默認(rèn)事件會導(dǎo)致我的子組件的默認(rèn)事件失效?
分析:
首先,我們看官網(wǎng)對event.preventDefault()這一方法的解釋,在繁體中文版的MDN網(wǎng)站中,只是簡單的提到了取消事件的預(yù)設(shè)行為,而不影響事件的傳遞。如字面意思,很好理解。
而在簡體中文版的MDN網(wǎng)站中,對于此事件描述的文字對比繁體版較多
在這里提到一個詞,叫顯示處理,不是很能理解這個詞。繁體版與簡體版的比較對應(yīng)下來,也能夠說的過去,所以這里并不能解決我們的疑問,到底為什么在父元素上調(diào)用了這個方法阻止默認(rèn)事件,子元素的默認(rèn)事件也消失了?
持續(xù)跟進(jìn):
翻遍了百度,我沒有找到有關(guān)于這個問題的解答,莫得辦法了,只有自己去試著找一些結(jié)論性的東西。
嘗試:
<!DOCTYPE html> <html lang="en"> <head> ? ? <meta charset="UTF-8"> ? ? <meta http-equiv="X-UA-Compatible" content="IE=edge"> ? ? <meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ? <title>Document</title> ? ? <style> ? ? ? ? #box{ ? ? ? ? ? ? height: 300px; ? ? ? ? ? ? overflow: auto; ? ? ? ? ? ? width:200px; ? ? ? ? ? ? padding: 40px; ? ? ? ? ? ? margin: 0 auto; ? ? ? ? ? ? background: grey; ? ? ? ? } ? ? ? ? #gdfather{ ? ? ? ? ? ? position: relative; ? ? ? ? ? ? height: 600px; ? ? ? ? ? ? overflow: auto; ? ? ? ? ? ? width:400px; ? ? ? ? ? ? margin: 40px; ? ? ? ? ? ? background: rgba(0, 255, 255, 0.219); ? ? ? ? } ? ? ? ? #father{ ? ? ? ? ? ? position: absolute; ? ? ? ? ? ? top: 20px; ? ? ? ? ? ? height: 200px; ? ? ? ? ? ? overflow: auto; ? ? ? ? ? ? width: 600px; ? ? ? ? ? ? margin: 40px; ? ? ? ? ? ? background-color: rgba(128, 128, 128, 0.349); ? ? ? ? } ? ? ? ? #son{ ? ? ? ? ? ? position: absolute; ? ? ? ? ? ? top: 20px; ? ? ? ? ? ? height: 1400px; ? ? ? ? ? ? width: 800px; ? ? ? ? ? ? margin: 40px; ? ? ? ? ? ? background-color: rgba(205, 92, 92, 0.26); ? ? ? ? } ? ? ? ? #box2{ ? ? ? ? ? ? display: flex; ? ? ? ? ? ? justify-content: center; ? ? ? ? ? ? align-items: center; ? ? ? ? ? ? flex-direction: column; ? ? ? ? ? ? height:200px; ? ? ? ? ? ? width: 200px; ? ? ? ? ? ? background-color: khaki; ? ? ? ? } ? ? </style> </head> <body> ? ? <div id='box'> ? ? ? ? <div id='gdfather'> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <p>祖先中的內(nèi)容</p> ? ? ? ? ? ? <div id='father'> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <p>父親中的內(nèi)容</p> ? ? ? ? ? ? ? ? <div id='son'> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? ? ? <p>兒子中的內(nèi)容</p> ? ? ? ? ? ? ? ? </div> ? ? ? ? ? ? </div> ? ? ? ? </div> ? ? </div> ? ? <div id='box2'> ? ? ? ? <input id="ipt" type="text"> ? ? ? ? <div id='inbox'> ? ? ? ? ? ? <input id='inIpt' type="text"> ? ? ? ? </div> ? ? </div> ? ? <script> ? ? ? ? let gdfather=document.getElementById('gdfather') ? ? ? ? let father=document.getElementById('father') ? ? ? ? let son=document.getElementById('son') ? ? ? ? gdfather.addEventListener('touchmove',(e)=>{ ? ? ? ? ? ? // console.log('gdfather') ? ? ? ? ? ? // e.preventDefault() ? ? ? ? }) ? ? ? ? father.addEventListener('touchmove',(e)=>{ ? ? ? ? ? ? // console.log('father') ? ? ? ? ? ? console.log(e.preventDefault.toString()) ? ? ? ? ? ? console.log(e) ? ? ? ? }) ? ? ? ? let box2=document.getElementById('box2') ? ? ? ? let inbox=document.getElementById('inbox') ? ? ? ? let ipt=document.getElementById('ipt') ? ? ? ? let inIpt=document.getElementById('inIpt') ? ? ? ? let events ? ? ? ? box2.addEventListener('keydown',(e)=>{ ? ? ? ? ? ? // e.preventDefault() ? ? ? ? ? ? console.log(e===events) ? ? ? ? }) ? ? ? ? ipt.addEventListener('keydown', (e)=>{ ? ? ? ? ? ? console.log(e===events) ? ? ? ? ? ? console.log(JSON.stringify(e)===JSON.stringify(events)) ? ? ? ? ? ? events=e ? ? ? ? }) ? ? ? ? inIpt.addEventListener('keydown', (e)=>{ ? ? ? ? ? ? // e.preventDefault() ? ? ? ? ? ? events.preventDefault() ? ? ? ? ? ? console.log(events) ? ? ? ? }) ? ? </script> </body> </html>
總結(jié)
元素并不擁有事件,實(shí)際上,元素只是對事件進(jìn)行了一個監(jiān)聽。就比如一個人進(jìn)行一場馬拉松比賽,這個人進(jìn)行比賽的這個過程,就是事件從誕生到結(jié)束的整個過程。而在比賽的途中,我們設(shè)置了一些里程點(diǎn),每一場馬拉松比賽都會在里程點(diǎn)設(shè)置對應(yīng)的補(bǔ)給,我們規(guī)定每到達(dá)一個補(bǔ)給點(diǎn)就會進(jìn)行補(bǔ)給,這個可以看作事件的默認(rèn)行為。當(dāng)事件每到達(dá)一個里程點(diǎn)時,我們可以在這個里程點(diǎn)做一些事,比如歡呼之類的(也就是設(shè)置事件監(jiān)聽),也可以啥都不做。這個里程點(diǎn)就是元素,而歡呼就是元素在監(jiān)聽到這個事件時我們設(shè)置的行為。
實(shí)際上,即使是同一個事件,所擁有的event也是不同的,這個在上面的118和119行可以進(jìn)行證明,而同一類型的事件在觸發(fā)時只會擁有這一個event,這一點(diǎn)通過118和115可以證明,對應(yīng)到馬拉松就是每一次馬拉松都是不同的,而一條路線上只可能進(jìn)行一場馬拉松比賽。當(dāng)我們阻止事件冒泡時,相當(dāng)于我們在跑到23公里時,放棄了這場比賽,那么在32公里處等著為我們歡呼的人就永遠(yuǎn)不會觸發(fā)這個動作。而我們在使用event.preventDefault()這個方法時,相當(dāng)于我們撤掉了所有的里程點(diǎn)的補(bǔ)給,自然也就沒有了默認(rèn)行為,但我們還在跑,原來在32公里處為我們歡呼的人依舊會為我們歡呼。
在通過上面的分析后,已經(jīng)可以很好的理解為什么在父組件中使用了preventDefault(),而子組件也沒有默認(rèn)行為了,因?yàn)樗械难a(bǔ)給都被撤掉了。即在這一條線上所有的默認(rèn)行為都沒有了。
e.preventDefault()與return false的區(qū)別
事件處理函數(shù)的返回值(return false)只對通過屬性注冊的處理函數(shù)才有意義;
也就是說如果我們不是通過addEventListener()函數(shù)來綁定事件的話,那么要禁止默認(rèn)事件的話,用的就是return false;
如果使用addEventListener()或者attachEvent()函數(shù)來綁定的話,就要使用e.preventDefault()方法或者設(shè)置事件對象的returnValue屬性來阻止默認(rèn)事件。
到此這篇關(guān)于關(guān)于js中e.preventDefault()的具體使用的文章就介紹到這了,更多相關(guān)js e.preventDefault()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何實(shí)現(xiàn)表格中行點(diǎn)擊時的漸擴(kuò)效果!
如何實(shí)現(xiàn)表格中行點(diǎn)擊時的漸擴(kuò)效果!...2007-01-01微信小程序頁面?zhèn)鞫鄠€參數(shù)跳轉(zhuǎn)頁面的實(shí)現(xiàn)方法
這篇文章主要介紹了微信小程序頁面?zhèn)鞫鄠€參數(shù)跳轉(zhuǎn)頁面的實(shí)現(xiàn)方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-05-05一道優(yōu)雅面試題分析js中fn()和return fn()的區(qū)別
這篇文章主要帶領(lǐng)大家深入理解JavaScript中 fn() 和 return fn() 的區(qū)別,感興趣的小伙伴們可以參考一下2016-07-07JavaScript編程設(shè)計模式之構(gòu)造器模式實(shí)例分析
這篇文章主要介紹了JavaScript編程設(shè)計模式之構(gòu)造器模式,簡單講述了構(gòu)造器模式的概念、原理,并結(jié)合實(shí)例形式分析了構(gòu)造器模式的定義與使用方法,需要的朋友可以參考下2017-10-10在JavaScript中查找字符串中最長單詞的三種方法(推薦)
這篇文章主要介紹了在JavaScript中查找字符串中最長單詞的三種方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01