摘要:三事件流規(guī)定事件包括三個(gè)階段,事件捕獲,處于目標(biāo)階段事件冒泡。一起來(lái)看添加新增加的,點(diǎn)擊發(fā)現(xiàn)沒有反應(yīng),說(shuō)明事件沒有綁定進(jìn)去,但是我們也并不想,每增加一個(gè)新元素,就為這個(gè)新元素綁定事件,重復(fù)低效率的工作應(yīng)當(dāng)避免去做。
本文共 1960 字,讀完只需 8 分鐘事件
用戶與網(wǎng)頁(yè)交互是通過事件實(shí)現(xiàn)的,事件剛開始是作為分擔(dān)服務(wù)器負(fù)載的一個(gè)手段,起初沒有統(tǒng)一的規(guī)范,直到 DOM2 級(jí),網(wǎng)景和 IE 才開始有各自的 API 規(guī)范。
對(duì)于事件的觸發(fā)機(jī)制,兩個(gè)公司都認(rèn)為頁(yè)面的觸發(fā)機(jī)制并不只是點(diǎn)擊了某個(gè)元素,就只觸發(fā)當(dāng)前目標(biāo)元素的事件。
比方說(shuō):頁(yè)面有多個(gè)同心圓,當(dāng)點(diǎn)擊最里面的圓時(shí),你其實(shí)也點(diǎn)擊了包含這個(gè)圓外面的那些圓。 兩個(gè)公司對(duì)這點(diǎn)的認(rèn)同是一致的,但是事件流的傳播順序上采用了不同的兩種方案來(lái)實(shí)現(xiàn),即事件冒泡和事件捕獲。
一、事件冒泡IE 瀏覽器從老版本開始就一直支持事件冒泡機(jī)制,所謂事件冒泡,指事件流開始是從較為具體的元素接收,一直傳播上不具體的元素上。
就是從目標(biāo)元素傳播到父級(jí)元素。
如下圖所示,如果點(diǎn)擊了 id 為 child 的元素后,事件流會(huì)從 child 一直傳播到 window 對(duì)象。
所有現(xiàn)代瀏覽器都支持事件冒泡。
二、事件捕獲由網(wǎng)景公司主導(dǎo)的事件捕獲則剛好和事件冒泡相反,事件流開始從不具體的元素觸發(fā),然后傳播到具體的元素上。簡(jiǎn)而言之就是從父級(jí)元素傳播到目標(biāo)元素。
由于事件捕獲是從 IE 9開始支持,不兼容老版本瀏覽器,所以使用的人比較少。
三、事件流DOM 規(guī)定事件包括三個(gè)階段,事件捕獲,處于目標(biāo)階段、事件冒泡。
從 IE 9 開始的瀏覽器規(guī)定,事件流的順序先是事件捕獲,會(huì)截獲到事件,然后是處于目標(biāo)階段,實(shí)際的目標(biāo)接收到事件,最后是事件冒泡,可以在這個(gè)階段對(duì)事件進(jìn)行響應(yīng)。
以之前的 child 元素為例,直到 child 元素接收到事件前(從 window 到 parent),都是事件捕獲階段。到了 child 元素,此時(shí)對(duì)事件進(jìn)行處理,隨后冒泡到 window 對(duì)象上,冒泡階段也是可以對(duì)事件進(jìn)行處理的。 基于事件冒泡能對(duì)事件進(jìn)行處理的特點(diǎn),隨后將講到與其有關(guān)的事件委托機(jī)制。
四、事件綁定HTML 與 事件的綁定有三種形式:
1. 2. var childEl = document.getElementById("child"); childEl.onclick = function() { console.log("hello"); } 3. var childEl = document.getElementById("child"); childEl.addEventListener("click", function() { console.log("hello"); }, false);
JavaScript 是單線程的語(yǔ)言,在遇到元素有事件觸發(fā)時(shí),會(huì)在事件隊(duì)列中尋找有沒有與這個(gè)事件綁定的函數(shù),如果沒有則什么都不做,如果有,則將該函數(shù)放到事件隊(duì)列的前面,等待主線程事件執(zhí)行完畢后執(zhí)行。
上述代碼第一種綁定,將事件寫在 html 中,表現(xiàn)和行為沒有解耦,是不建議這樣寫代碼的。
第二種綁定,將事件綁定在元素對(duì)象上,這種寫法主要是容易發(fā)生事件的覆蓋。
第三種綁定,首先,第三個(gè)參數(shù)為布爾值,默認(rèn)為 false, 表示在事件冒泡階段調(diào)用事件處理程序,如果為 true, 則表示在事件捕獲階段調(diào)用事件處理函數(shù)。
當(dāng)我們想處理完一次事件后,將不想在處理該元素的事件綁定時(shí),應(yīng)該將元素的事件綁定置為空,如果容易發(fā)生內(nèi)存泄漏。
第一種寫法: childEl.onclick = null; 第三種寫法: function eventHandler() { console.log("hello"); } childEl.addEventListener("click", eventHandler, false); childEl.removeEventListener("click", eventHandler, false);五、事件委托(事件代理)
事件委托是利用事件冒泡的性質(zhì),事件流開始是從較為具體的元素接收,一直傳播上不具體的元素上。
首先,假如有一個(gè)列表 ul,每個(gè)列表元素 li 點(diǎn)擊會(huì)觸發(fā)事件處理程序,顯然,如果一個(gè)一個(gè)地給元素綁定事件, 效率肯定不好。
與此同時(shí),當(dāng)新增一個(gè)元素時(shí),事件不見得會(huì)綁定成功。一起來(lái)看:
新增加的 menu-new,點(diǎn)擊發(fā)現(xiàn)沒有反應(yīng),說(shuō)明事件沒有綁定進(jìn)去,但是我們也并不想,每增加一個(gè)新元素,就為這個(gè)新元素綁定事件,重復(fù)低效率的工作應(yīng)當(dāng)避免去做。
我們通過事件委托的思路來(lái)想,事件流的傳播,目標(biāo)元素本身依然會(huì)有事件,但同時(shí),冒泡出去后,更高層次的 dom 也能處理事件程序。那么,我們只需要給高層次節(jié)點(diǎn)綁定事件,通過判斷具體是觸發(fā)的哪個(gè)子節(jié)點(diǎn),再做相應(yīng)的事件處理。
menu 列表的每個(gè)子菜單元素的事件都能正確響應(yīng),新增的 menu-new 同樣也能正確響應(yīng)事件。
事件委托的好處在于,我們不用給每個(gè)元素都一一地手動(dòng)添加綁定事件,避免重復(fù)低效的工作。
其次,事件委托更少得獲取 dom, 初始化元素對(duì)象和事件函數(shù),能有效減少內(nèi)存占用。
每當(dāng)將事件程序指定給元素時(shí),html 代碼和 js 代碼之間就建立了一個(gè)連接,這種連接越多,網(wǎng)頁(yè)就執(zhí)行起來(lái)越慢,所以事件委托能有效減少連接樹,提高網(wǎng)頁(yè)性能。
總結(jié)用戶與網(wǎng)頁(yè)的交互是通過事件進(jìn)行的,事件模型分為事件冒泡和事件捕獲,事件冒泡的兼容性更好,應(yīng)用更廣,同時(shí)通過事件冒泡,可以建立事件委托,提升網(wǎng)頁(yè)性能。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/108760.html
摘要:宏任務(wù)需要多次事件循環(huán)才能執(zhí)行完。總結(jié)事件循環(huán)是和事件調(diào)用機(jī)制的核心,保證了頁(yè)面可以有序無(wú)阻塞的進(jìn)行。事件循環(huán)的主要邏輯是先執(zhí)行調(diào)用棧,直到清空調(diào)用棧只剩下全局上下文。微任務(wù)執(zhí)行后完,進(jìn)行頁(yè)面渲染和垃圾回收后進(jìn)行下一輪事件循環(huán)。 準(zhǔn)備知識(shí) 1. 進(jìn)程(process) 進(jìn)程是系統(tǒng)資源分配一個(gè)獨(dú)立單位,一個(gè)程序至少有一個(gè)進(jìn)程。比方說(shuō):一個(gè)工廠代表一個(gè) CPU, 一個(gè)車間就是一個(gè)進(jìn)程,任一...
摘要:在這個(gè)事件發(fā)生期間,調(diào)用可阻止?jié)L動(dòng)當(dāng)手指從屏幕上移開時(shí)觸發(fā)。關(guān)于此事件的確切觸發(fā)事件,文檔中沒有明確說(shuō)明。特定于事件目標(biāo)的對(duì)象的數(shù)組。 JS事件模型 事件模型以及周邊 事件捕獲 事件冒泡 事件觸發(fā) 移動(dòng)端事件模擬 事件委托 事件流 事件捕獲(event capturing)&事件冒泡(event bubbling) 給inner,out均綁定點(diǎn)擊事件.點(diǎn)擊inne...
摘要:將元素作為對(duì)象的鍵,默認(rèn)鍵對(duì)應(yīng)的值為如果對(duì)象中沒有這個(gè)鍵,則將這個(gè)元素放入結(jié)果數(shù)組中去。 前言 數(shù)組去重在日常開發(fā)中的使用頻率還是較高的,也是網(wǎng)上隨便一抓一大把的話題,所以,我寫這篇文章目的在于歸納和總結(jié),既然很多人都在提的數(shù)組去重,自己到底了解多少呢。又或者是如果自己在開發(fā)中遇到了去重的需求,自己能想到更好的解決方案嗎。 這次我們來(lái)理一理怎么做數(shù)組去重才能做得最合適,既要考慮兼容性,...
摘要:而異步則是相反,調(diào)用在發(fā)出之后,這個(gè)調(diào)用就直接返回了,所以沒有返回結(jié)果而是在調(diào)用發(fā)出后,被調(diào)用者通過狀態(tài)通知來(lái)通知調(diào)用者,或通過回調(diào)函數(shù)處理這個(gè)調(diào)用。總結(jié)回調(diào)函數(shù)是異步編程中的基石,但同時(shí)也存在很多問題,不太適合人類自然語(yǔ)言的線性思維習(xí)慣。 為什么 JS 是單線程? 眾所周知,Javascript 語(yǔ)言的執(zhí)行環(huán)境是單線程(single thread)。 所謂單線程,就是指一次只能完成一...
摘要:道阻且長(zhǎng)啊前端面試總結(jié)前端面試筆試面試騰訊一面瀏覽器工作原理瀏覽器的主要組件包括用戶界面包括地址欄后退前進(jìn)按鈕書簽?zāi)夸洖g覽器引擎用來(lái)查詢及操作渲染引擎的接口渲染引擎渲染界面和是基于兩種渲染引擎構(gòu)建的,使用自主研發(fā)的渲染引擎,和都使用網(wǎng)絡(luò)用來(lái) 道阻且長(zhǎng)啊TAT(前端面試總結(jié)) 前端 面試 筆試 面試 騰訊一面 1.瀏覽器工作原理 瀏覽器的主要組件包括: 用戶界面- 包括地址欄、后退/前...
閱讀 2815·2023-04-25 15:01
閱讀 3044·2021-11-23 10:07
閱讀 3362·2021-10-12 10:12
閱讀 3452·2021-08-30 09:45
閱讀 2191·2021-08-20 09:36
閱讀 3583·2019-08-30 12:59
閱讀 2429·2019-08-26 13:52
閱讀 932·2019-08-26 13:24