国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

關(guān)于JS中事件代理的解析

KavenFan / 2420人閱讀

摘要:事件代理原理事件代理本質(zhì)上來說是利用事件冒泡的機(jī)制來進(jìn)行實(shí)現(xiàn)的。

概述

一般來說,我們?cè)跒榍岸隧撁嬖O(shè)計(jì)交互的的時(shí)候往往需要為DOM元素添加事件處理程序。但是很多時(shí)候頁面的DOM元素的結(jié)構(gòu)和層級(jí)會(huì)很復(fù)雜,如果我們?yōu)樗行枰砑邮录幚淼腄OM元素一一綁定上事件處理程序,那么不僅編寫出的代碼會(huì)很繁雜,整個(gè)頁面的性能也會(huì)很低下。比如我們有一個(gè)有序或者無序的列表,其中包裹了數(shù)百個(gè)子節(jié)點(diǎn)li,一般來說,在通過選擇器拿到元素集合后,我們會(huì)用for循環(huán)對(duì)集合進(jìn)行遍歷,然后為其添加事件處理方法,這么做會(huì)帶來什么結(jié)果呢,在JS引擎中,代碼操作的DOM數(shù)量和添加的事件處理程序數(shù)量直接關(guān)系到頁面的整體性能。操作的DOM數(shù)量越多,對(duì)DOM的訪問次數(shù)越多,瀏覽器的重繪次數(shù)就越來越多,頁面的響應(yīng)速度和運(yùn)行性能也就越來越差。所以,在進(jìn)行程序優(yōu)化的過程,其中一個(gè)重要的思路就是減少DOM的操作。

這時(shí),事件代理存在的重要意義就體現(xiàn)出來了,它為我們提供了一種新的解決為大量類似的DOM元素添加事件處理的解決方案。只為一個(gè)容器或者說父節(jié)點(diǎn)添加一次事件處理程序,就達(dá)成了控制這個(gè)容器中一系列元素的目標(biāo),大大的減少了瀏覽器對(duì)DOM的訪問。

事件代理原理

事件代理本質(zhì)上來說是利用事件冒泡的機(jī)制來進(jìn)行實(shí)現(xiàn)的。何為事件冒泡呢,百科中的解釋是當(dāng)事件發(fā)生后,這個(gè)事件就要開始傳播(從里到外或者從外向里)。為什么要傳播呢?因?yàn)槭录幢旧恚赡埽┎]有處理事件的能力,即處理事件的函數(shù)(方法)并未綁定在該事件源上。例如我們點(diǎn)擊一個(gè)按鈕時(shí),就會(huì)產(chǎn)生一個(gè)click事件,但這個(gè)按鈕本身可能不能處理這個(gè)事件,事件必須從這個(gè)按鈕傳播出去,從而到達(dá)能夠處理這個(gè)事件的代碼中(例如我們給按鈕的onclick屬性賦一個(gè)函數(shù)的名字,就是讓這個(gè)函數(shù)去處理該按鈕的click事件),或者按鈕的父級(jí)綁定有事件函數(shù),當(dāng)該點(diǎn)擊事件發(fā)生在按鈕上,按鈕本身并無處理事件函數(shù),則傳播到父級(jí)去處理。

相關(guān)實(shí)現(xiàn)

具體怎么實(shí)現(xiàn)事件代理呢,我們來看一些簡(jiǎn)單的相關(guān)例子:

先寫一個(gè)簡(jiǎn)單的有序列表結(jié)構(gòu)。

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5

比如我們想要實(shí)現(xiàn)的是點(diǎn)擊li,彈出li的序列。如果要直接操作li。

var lists = document.querySelectorAll("li");
for(let i = 0; i < lists.length; i ++){
    lists[i].onclick =function () {
        alert(lists[i].innerText);
    }
}

通過選擇器拿到了li的集合,然后進(jìn)行遍歷并一一綁定點(diǎn)擊事件,如果使用事件代理來實(shí)現(xiàn)呢

var lists = document.querySelector("ol");
lists.onclick = function (event) {
    alert(event.target.innerText);
}

通過選擇器拿到li的容器也就是父節(jié)點(diǎn)ol,然后只綁定一次點(diǎn)擊事件,并通過event對(duì)象提供的屬性target指向容器的子節(jié)點(diǎn),然后彈出該子節(jié)點(diǎn)的文本內(nèi)容。需要了解的是,event對(duì)象提供了兩個(gè)屬性,分別是currentTarget和target,前者指向的是綁定事件的當(dāng)前節(jié)點(diǎn),后者則指向當(dāng)前節(jié)點(diǎn)的一級(jí)子節(jié)點(diǎn)。當(dāng)我們面臨事件冒泡和事件捕獲時(shí),這兩個(gè)屬性能夠?yàn)槲覀兲峁└叩撵`活度。

上訴例子中,我們需要添加事件的DOM元素都是相同的,事件的種類也是一樣的,如果我們面對(duì)的是結(jié)構(gòu)更復(fù)雜一些的DOM集合呢,來看下面的例子。

DOM結(jié)構(gòu):

在這樣的DOM結(jié)構(gòu)中,我們要為四種不同的元素添加事件控制,如果只是通過target指向的話是無法實(shí)現(xiàn)的,需要挖掘target更深層的屬性來進(jìn)行條件判斷,而target具備的屬性就是指向的子節(jié)點(diǎn)所具備的屬性,比如nodeName、id、className、value等

let box = document.querySelector(".wrap");
box.onclick = function (event) {
    if(event.target.nodeName === "button"){
        //...
    }else if(event.target.value === "提交"){
        //...
    }else if(event.target.className === "text"){
        //...
    }else{
        //...
    }
};

這樣我們同樣只在父節(jié)點(diǎn)上綁定一次事件就完成了我們想要的效果,無論是編碼效率和性能損耗都比不適用事件代理的情況下更加優(yōu)化。我們可以發(fā)現(xiàn),相比與遍歷元素集合的方式,事件代理最大的好處就是減少了DOM的操作,從來提升了效能。

適用場(chǎng)景

事件代理并非在所有場(chǎng)景中都適用的,在使用事件代理時(shí),我們需要考慮添加事件處理的父節(jié)點(diǎn)能否觸發(fā)我們想要綁定的事件,比如:


當(dāng)我們想為容器中的文本框綁定blur事件改變框體顏色時(shí)

let box = document.querySelector(".wrap");
box.addEventListener("blur",function (event) {
    event.target.style.borderColor = "red";
});

我們發(fā)現(xiàn)這樣做是無法生效的,應(yīng)為div元素是無法觸發(fā)onblur事件的,同時(shí)還有其他有關(guān)的輸入框事件也是無法觸發(fā)的,如oninput、onfocus等。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/100406.html

相關(guān)文章

  • 一文看透瀏覽器架構(gòu)

    摘要:值得注意不同的瀏覽器使用不同的。今天截至年月,在瀏覽器進(jìn)程中運(yùn)行。這意味著瀏覽器進(jìn)程包含一個(gè)實(shí)例,這是一個(gè)潛在的安全漏洞。 本文由云+社區(qū)發(fā)表作者:廖彩明 在從事前端開發(fā)過程中,瀏覽器作為最重要的開發(fā)環(huán)境,瀏覽器基礎(chǔ)是是前端開發(fā)人員必須掌握的基礎(chǔ)知識(shí)點(diǎn),它貫穿著前端的整個(gè)網(wǎng)絡(luò)體系。對(duì)瀏覽器原理的了解,決定著編寫前端代碼性能的上限。瀏覽器作為JS的運(yùn)行環(huán)境,學(xué)習(xí)總結(jié)下現(xiàn)代瀏覽器的相關(guān)知識(shí)...

    sunsmell 評(píng)論0 收藏0
  • 【Step-By-Step】一周面試題深入解析 / 周刊 03

    摘要:禁止內(nèi)聯(lián)腳本執(zhí)行規(guī)則較嚴(yán)格,目前發(fā)現(xiàn)使用。合理使用上報(bào)可以及時(shí)發(fā)現(xiàn),利于盡快修復(fù)問題。因?yàn)槭录?huì)從目標(biāo)元素一層層冒泡至對(duì)象。允許給一個(gè)事件注冊(cè)多個(gè)監(jiān)聽。表示在捕獲階段觸發(fā),表示在冒泡階段觸發(fā)。 關(guān)于【Step-By-Step】 Step-By-Step (點(diǎn)擊進(jìn)入項(xiàng)目) 是我于 2019-05-20 開始的一個(gè)項(xiàng)目,每個(gè)工作日發(fā)布一道面試題。每個(gè)周末我會(huì)仔細(xì)閱讀大家的答案,整理最一份...

    hedge_hog 評(píng)論0 收藏0
  • 前端面試之路二(javaScript基礎(chǔ)整理)

    摘要:在標(biāo)簽中添加屬性,本質(zhì)上是跟在標(biāo)簽里面寫屬性時(shí)一樣的,所以屬性值最終都會(huì)編譯為字符串類型。這個(gè)節(jié)點(diǎn)包括很多,比如,以及一些方法等方法。一個(gè)對(duì)象有很多,該集合名字為,里面有其他以及,里面有很多。 一、變量類型和計(jì)算 JS中使用typeof能得到哪些類型 變量類型 值類型:變量本身就是含有賦予給它的數(shù)值的,它的變量本身及保存的數(shù)據(jù)都存儲(chǔ)在棧的內(nèi)存塊當(dāng)中 引用類型:引用類型當(dāng)然是分配到...

    AbnerMing 評(píng)論0 收藏0
  • 前端面試題目匯總

    摘要:線程在執(zhí)行過程中與進(jìn)程還是有區(qū)別的。但是線程不能夠獨(dú)立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制。從邏輯角度來看,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行。 關(guān)于js 1.原型鏈 2.AJAX請(qǐng)求數(shù)據(jù)時(shí)解決緩存的辦法3.js的繼承 ...

    lastSeries 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<