欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript 事件代理需要注意的地方

 更新時(shí)間:2020年09月08日 08:57:03   作者:前端小蜜蜂  
這篇文章主要介紹了JavaScript 事件代理需要注意的地方,幫助大家更好的理解和學(xué)習(xí)JavaScript,感興趣的朋友可以了解下

我們知道,如果給 form 里面的 button 元素綁定事件,需要考慮它是否會(huì)觸發(fā) form 的 submit 行為。除此之外,其它場(chǎng)合給 button 元素綁定事件,你幾乎不用擔(dān)心這個(gè)事件會(huì)有什么非預(yù)期的附加效果,很自然地會(huì)這樣寫(xiě)事件處理代碼:

var button = document.querySelector('button')
button.addEventListener('click', function (e) {
 console.log('點(diǎn)擊了按鈕')
})

你之所以放心這么寫(xiě),是因?yàn)檫@個(gè) button 元素沒(méi)有使用事件代理,即沒(méi)有代理任何子元素的事件。

事件代理的意思是,你要為一個(gè)元素綁定事件,但你不是直接把事件綁定到這個(gè)元素自己身上,而是綁定到這個(gè)元素的父元素上。當(dāng)子元素的某個(gè)事件(比如點(diǎn)擊事件)觸發(fā)時(shí),它的父元素相同的事件也會(huì)觸發(fā)(我們常說(shuō)的事件冒泡),此時(shí)我們說(shuō)父元素代理了子元素的事件。

舉個(gè)例子,比如一個(gè) button 元素中包含一個(gè)齒輪圖標(biāo):

<button>
 <svg>
 <use xlink:href="#gear" rel="external nofollow" ></use>
 </svg>
</button>

當(dāng)用戶(hù)點(diǎn)擊齒輪圖標(biāo),必然要觸發(fā) click 事件,但你并不會(huì)直接綁定事件到 svg 或 use 元素上,而是綁定到它們的父元素 button 上。即:

document.querySelector('button').addEventListener('click', function (e) {
 console.log('點(diǎn)擊了按鈕')
})

這種情況,我們可以說(shuō),button 元素代理了它的所有子元素的 click 事件。

但是,出現(xiàn)這種事件代理的情況時(shí),我們就得小心了。

為了更直觀地說(shuō)明問(wèn)題,我們把“父”元素上升到頂層的 document 元素:

document.documentElement.addEventListener('click', function (e) {
 console.log('我被點(diǎn)擊了')
})

只要網(wǎng)頁(yè)中任意一個(gè)位置被點(diǎn)擊了,都會(huì)觸發(fā)綁定在 document 元素上的點(diǎn)擊事件。​ 想要知道事件具體是發(fā)生在哪個(gè)元素上面,可以通過(guò)事件對(duì)象提供的 target 屬性來(lái)判斷。

document.documentElement.addEventListener('click', function (e) {
 console.log(e.target)
})

我們很容易知道事件具體是發(fā)生在哪個(gè)元素身上的。于是在上面的示例中,如果父元素 document 想在按鈕被點(diǎn)擊時(shí)做點(diǎn)什么事情,我們很自然地會(huì)這么寫(xiě):

document.documentElement.addEventListener('click', function (e) {
 if (e.target.tagName === 'BUTTON') {
 console.log('按鈕被點(diǎn)擊了')
 }
})

這時(shí)問(wèn)題就出現(xiàn)了,按鈕即使被點(diǎn)擊了 if 條件也不一定成立,即也不一定會(huì)輸出“按鈕被點(diǎn)擊了”。因?yàn)橛脩?hù)在按鈕上的某個(gè)位置點(diǎn)擊了,根據(jù)用戶(hù)點(diǎn)擊的位置,e.target 可能是下面三種情況:

  • BUTTON 元素
  • SVG 元素
  • USE 元素

實(shí)際的情況是這樣的:

我們真正的意圖是,只要點(diǎn)擊是發(fā)生在按鈕上面,不論是按鈕的哪個(gè)位置,我們都應(yīng)視為按鈕被點(diǎn)擊了。 嗯,簡(jiǎn)單,我們?cè)俑囊幌?,這樣寫(xiě):

document.documentElement.addEventListener('click', function (e) {
 if (['BUTTON', 'SVG', 'USE'].includes(e.target.tagName.toUpperCase())) {
 // 點(diǎn)擊的是按鈕
 }
})

這樣似乎沒(méi)什么問(wèn)題,也確實(shí)可以達(dá)到目的,但看上去總是有些別扭。因?yàn)檫@種情況對(duì)于最上層的 document 來(lái)說(shuō),得知道每個(gè)子元素的情況,本來(lái)我只需要關(guān)心離我最近的 button 元素就可以了。

根據(jù) OOP 對(duì)內(nèi)封裝的思想,button 元素內(nèi)部的事情應(yīng)該在內(nèi)部消化掉,其子元素對(duì)外不可見(jiàn),應(yīng)該只暴露 button 元素本身。依據(jù)這個(gè)思想和事件冒泡的特點(diǎn),我們就有了比較好的解決辦法:只需要禁止 button 內(nèi)部元素的事件響應(yīng)(包括事件冒泡)而只允許 button 元素本身的事件發(fā)生就行。有兩種方式可以實(shí)現(xiàn)這個(gè)目的。

一種是使用 CSS 禁止 button 內(nèi)部元素的事件響應(yīng):

button > * {
 pointer-events: none;
}

另一種是使用 JS 來(lái)阻止 button 內(nèi)部元素的事件響應(yīng)(包括事件冒泡):

document.querySelector('button > svg').addEventListener('click', function (e) {
 e.stopPropagation()
 e.preventDefault()
})

document.querySelector('button').addEventListener('click', function (e) {
 console.log(e.target.tagName)
})

這兩種方式都能達(dá)到我們預(yù)期的效果:

綜上,針對(duì)特定元素進(jìn)行事件處理時(shí),如果該元素有事件代理的情況,就要小心處理它所代理的子元素。

以上就是JavaScript 事件代理需要注意的地方的詳細(xì)內(nèi)容,更多關(guān)于JavaScript 事件代理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript日期時(shí)間與時(shí)間戳的轉(zhuǎn)換函數(shù)分享

    JavaScript日期時(shí)間與時(shí)間戳的轉(zhuǎn)換函數(shù)分享

    這篇文章主要介紹了JavaScript日期時(shí)間與時(shí)間戳的轉(zhuǎn)換函數(shù)分享,本文給出兩個(gè)函數(shù)實(shí)現(xiàn)日期時(shí)間和時(shí)間戳間的轉(zhuǎn)換,需要的朋友可以參考下
    2015-01-01
  • javascript表單驗(yàn)證和Window詳解

    javascript表單驗(yàn)證和Window詳解

    這篇文章主要詳細(xì)介紹了javascript表單驗(yàn)證和Window,并附上了示例代碼,非常使用,對(duì)于我們更好的了解表單驗(yàn)證和Window很有幫助,這里推薦給大家
    2014-12-12
  • BootStrap實(shí)現(xiàn)輪播圖效果(收藏)

    BootStrap實(shí)現(xiàn)輪播圖效果(收藏)

    這篇文章主要介紹了BootStrap實(shí)現(xiàn)輪播圖效果,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-12-12
  • js實(shí)現(xiàn)顏色階梯漸變效果(Gradient算法)

    js實(shí)現(xiàn)顏色階梯漸變效果(Gradient算法)

    在色彩中,色相、明度、純度也都可以產(chǎn)生漸變效果,并會(huì)表現(xiàn)出具有豐富層次的美感。本文主要講述兩種顏色RGB數(shù)值的梯級(jí)漸變算法。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • JavaScript常用數(shù)組去重的方法及對(duì)比詳解

    JavaScript常用數(shù)組去重的方法及對(duì)比詳解

    數(shù)組去重在面試和工作中都是比較容易見(jiàn)到的問(wèn)題。這篇文章主要是來(lái)測(cè)試多個(gè)方法,對(duì)下面這個(gè)數(shù)組的去重結(jié)果進(jìn)行分析討論,需要的可以參考一下
    2022-07-07
  • 詳解Webpack4多頁(yè)應(yīng)用打包方案

    詳解Webpack4多頁(yè)應(yīng)用打包方案

    這篇文章主要介紹了詳解Webpack4多頁(yè)應(yīng)用打包方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • bootstrap響應(yīng)式導(dǎo)航條模板使用詳解(含下拉菜單,彈出框)

    bootstrap響應(yīng)式導(dǎo)航條模板使用詳解(含下拉菜單,彈出框)

    這篇文章主要為大家詳細(xì)介紹了bootstrap響應(yīng)式導(dǎo)航條模板使用詳解,含下拉菜單,彈出框效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • JavaScript入門(mén)基礎(chǔ)

    JavaScript入門(mén)基礎(chǔ)

    在學(xué)習(xí)JavaScript之前,必須具備HTML和CSS知識(shí),Javascript是一種解釋性的,基于對(duì)象的腳本語(yǔ)言(aninterpreted,object-basedscriptinglanguage)。這篇文章主要講解JavaScript入門(mén)基礎(chǔ),需要的朋友可以參考下
    2015-08-08
  • js實(shí)現(xiàn)注冊(cè)頁(yè)面校驗(yàn)功能

    js實(shí)現(xiàn)注冊(cè)頁(yè)面校驗(yàn)功能

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)注冊(cè)頁(yè)面校驗(yàn)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • JavaScript(JS) 壓縮 / 混淆 / 格式化 批處理工具

    JavaScript(JS) 壓縮 / 混淆 / 格式化 批處理工具

    本工具所有的功能實(shí)現(xiàn)都是由 ttp://jscompress.sinaapp.com/api 處理.(包括現(xiàn)在可以使用的這個(gè)在線壓縮)
    2010-12-12

最新評(píng)論