摘要:而事件分為個級別級事件處理,級事件處理和級事件處理。一個事件發生后,會在子元素和父元素之間傳播。也就是說,始終是監聽事件者,而是事件的真正發出者。五參考文章級別與事件事件機制解惑事件模型事件委托詳解事件的學與記和和的區別
前言
本文主要介紹DOM事件級別、DOM事件模型、事件流、事件代理和Event對象常見的應用,希望對你們有些幫助和啟發!
本文首發地址為GitHub博客,寫文章不易,請多多支持與關注!
DOM級別一共可以分為四個級別:DOM0級、DOM1級、DOM2級和DOM3級。而DOM事件分為3個級別:DOM 0級事件處理,DOM 2級事件處理和DOM 3級事件處理。由于DOM 1級中沒有事件的相關內容,所以沒有DOM 1級事件。
1.DOM 0級事件el.onclick=function(){}
// 例1 var btn = document.getElementById("btn"); btn.onclick = function(){ alert(this.innerHTML); }
當希望為同一個元素/標簽綁定多個同類型事件的時候(如給上面的這個btn元素綁定3個點擊事件),是不被允許的。DOM0事件綁定,給元素的事件行為綁定方法,這些方法都是在當前元素事件行為的冒泡階段(或者目標階段)執行的。
2.DOM 2級事件el.addEventListener(event-name, callback, useCapture)
event-name: 事件名稱,可以是標準的DOM事件
callback: 回調函數,當事件觸發時,函數會被注入一個參數為當前的事件對象 event
useCapture: 默認是false,代表事件句柄在冒泡階段執行
// 例2 var btn = document.getElementById("btn"); btn.addEventListener("click", test, false); function test(e){ e = e || window.event; alert((e.target || e.srcElement).innerHTML); btn.removeEventListener("click", test) } //IE9-:attachEvent()與detachEvent()。 //IE9+/chrom/FF:addEventListener()和removeEventListener()
IE9以下的IE瀏覽器不支持 addEventListener()和removeEventListener(),使用 attachEvent()與detachEvent() 代替,因為IE9以下是不支持事件捕獲的,所以也沒有第三個參數,第一個事件名稱前要加on。
3.DOM 3級事件在DOM 2級事件的基礎上添加了更多的事件類型。
UI事件,當用戶與頁面上的元素交互時觸發,如:load、scroll
焦點事件,當元素獲得或失去焦點時觸發,如:blur、focus
鼠標事件,當用戶通過鼠標在頁面執行操作時觸發如:dblclick、mouseup
滾輪事件,當使用鼠標滾輪或類似設備時觸發,如:mousewheel
文本事件,當在文檔中輸入文本時觸發,如:textInput
鍵盤事件,當用戶通過鍵盤在頁面上執行操作時觸發,如:keydown、keypress
合成事件,當為IME(輸入法編輯器)輸入字符時觸發,如:compositionstart
變動事件,當底層DOM結構發生變化時觸發,如:DOMsubtreeModified
同時DOM3級事件也允許使用者自定義一些事件。
二、DOM事件模型和事件流DOM事件模型分為捕獲和冒泡。一個事件發生后,會在子元素和父元素之間傳播(propagation)。這種傳播分成三個階段。
(1)捕獲階段:事件從window對象自上而下向目標節點傳播的階段;
(2)目標階段:真正的目標節點正在處理事件的階段;
(3)冒泡階段:事件從目標節點自下而上向window對象傳播的階段。
DOM事件捕獲的具體流程捕獲是從上到下,事件先從window對象,然后再到document(對象),然后是html標簽(通過document.documentElement獲取html標簽),然后是body標簽(通過document.body獲取body標簽),然后按照普通的html結構一層一層往下傳,最后到達目標元素。
而事件冒泡的流程剛好是事件捕獲的逆過程。
接下來我們看個事件冒泡的例子:
// 例3...... window.onclick = function() { console.log("window"); }; document.onclick = function() { console.log("document"); }; document.documentElement.onclick = function() { console.log("html"); }; document.body.onclick = function() { console.log("body"); } outer.onclick = function(ev) { console.log("outer"); }; inner.onclick = function(ev) { console.log("inner"); };
正如我們上面提到的onclick給元素的事件行為綁定方法都是在當前元素事件行為的冒泡階段(或者目標階段)執行的。
三、事件代理(事件委托)由于事件會在冒泡階段向上傳播到父節點,因此可以把子節點的監聽函數定義在父節點上,由父節點的監聽函數統一處理多個子元素的事件。這種方法叫做事件的代理(delegation)。
1.優點減少內存消耗,提高性能
假設有一個列表,列表之中有大量的列表項,我們需要在點擊每個列表項的時候響應一個事件
// 例4
如果給每個列表項一一都綁定一個函數,那對于內存消耗是非常大的,效率上需要消耗很多性能。借助事件代理,我們只需要給父容器ul綁定方法即可,這樣不管點擊的是哪一個后代元素,都會根據冒泡傳播的傳遞機制,把容器的click行為觸發,然后把對應的方法執行,根據事件源,我們可以知道點擊的是誰,從而完成不同的事。
動態綁定事件
在很多時候,我們需要通過用戶操作動態的增刪列表項元素,如果一開始給每個子元素綁定事件,那么在列表發生變化時,就需要重新給新增的元素綁定事件,給即將刪去的元素解綁事件,如果用事件代理就會省去很多這樣麻煩。
2.如何實現接下來我們來實現上例中父層元素 #list 下的 li 元素的事件委托到它的父層元素上:
// 給父層元素綁定事件 document.getElementById("list").addEventListener("click", function (e) { // 兼容性處理 var event = e || window.event; var target = event.target || event.srcElement; // 判斷是否匹配目標元素 if (target.nodeName.toLocaleLowerCase === "li") { console.log("the content is: ", target.innerHTML); } });四、Event對象常見的應用
event. preventDefault()
如果調用這個方法,默認事件行為將不再觸發。什么是默認事件呢?例如表單一點擊提交按鈕(submit)跳轉頁面、a標簽默認頁面跳轉或是錨點定位等。
很多時候我們使用a標簽僅僅是想當做一個普通的按鈕,點擊實現一個功能,不想頁面跳轉,也不想錨點定位。
//方法一: 鏈接
也可以通過JS方法來阻止,給其click事件綁定方法,當我們點擊A標簽的時候,先觸發click事件,其次才會執行自己的默認行為
//方法二: 鏈接
//方法三: 鏈接
接下來我們看個例子:輸入框最多只能輸入六個字符,如何實現?
// 例5
event.stopPropagation() & event.stopImmediatePropagation()
event.stopPropagation() 方法阻止事件冒泡到父元素,阻止任何父事件處理程序被執行。上面提到事件冒泡階段是指事件從目標節點自下而上向window對象傳播的階段。
我們在例4的inner元素click事件上,添加event.stopPropagation()這句話后,就阻止了父事件的執行,最后只打印了"inner"。
inner.onclick = function(ev) { console.log("inner"); ev.stopPropagation(); };
stopImmediatePropagation 既能阻止事件向父元素冒泡,也能阻止元素同事件類型的其它監聽器被觸發。而 stopPropagation 只能實現前者的效果。我們來看個例子:
...... const btn = document.querySelector("#btn"); btn.addEventListener("click", event => { console.log("btn click 1"); event.stopImmediatePropagation(); }); btn.addEventListener("click", event => { console.log("btn click 2"); }); document.body.addEventListener("click", () => { console.log("body click"); }); // btn click 1
如上所示,使用 stopImmediatePropagation后,點擊按鈕時,不僅body綁定事件不會觸發,與此同時按鈕的另一個點擊事件也不觸發。
event.target & event.currentTarget
老實說這兩者的區別,并不好用文字描述,我們先來看個例子:
當我們點擊最里層的元素d的時候,會依次輸出:
target:d¤tTarget:d target:d¤tTarget:c target:d¤tTarget:b target:d¤tTarget:a
從輸出中我們可以看到,event.target指向引起觸發事件的元素,而event.currentTarget則是事件綁定的元素,只有被點擊的那個目標元素的event.target才會等于event.currentTarget。也就是說,event.currentTarget始終是監聽事件者,而event.target是事件的真正發出者。
五、參考文章DOM級別與DOM事件
DOM事件機制解惑
事件模型
JavaScript 事件委托詳解
JavaScript 事件的學與記:stopPropagation 和 stopImmediatePropagation
event.target和event.currentTarget的區別
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99732.html
摘要:使用來移除事件,參數必須與要移除的事件處理函數地址指針相同。在低版本瀏覽器中,綁定級事件的方法為中的級事件的事件處理程序都是在冒泡階段執行的。 JavaScript中幾個最重要的大知識點 面向對象 DOM事件 異步交互ajax 事件 事件就是文檔和瀏覽器的瞬間交互行為 1.事件類型 點擊: click 滾輪: scroll 滑動: move 進入: enter 加載: load ...
摘要:另外第三方也可以通過的事件插件機制來合成自定義事件,盡管很少人這么做。抽象跨平臺事件機制。打算干預事件的分發。事件是的一個自定義事件,旨在規范化表單元素的變動事件。 showImg(https://segmentfault.com/img/remote/1460000019961124?w=713&h=307); 當我們在組件上設置事件處理器時,React并不會在該DOM元素上直接綁定...
摘要:本博客大概介紹一下的事件機制,并給出整體的設計圖,但不涉及底層的源碼結構分析。整個設計圖以上是對的合成事件一個大概的介紹,里面還有很多細節和原理沒說到,有興趣的同學可以進一步研究一下源碼的細節。 好久沒寫博客了,前段時間太忙以至于平時的積累都記錄在內網的wiki里,趁著這幾天有空,將這段時間所積累的干貨慢慢的分享出來,如果內容有不正確的地方,歡迎糾正。 本博客大概介紹一下react的事...
摘要:深入理解事件機制一事件流事件就是當用戶或者瀏覽器自身執行的某種動作,諸如等都是事件的名稱,那響應個事件的函數就稱為事件處理程序事件處理函數事件句柄。 深入理解js Dom事件機制(一)——事件流 事件就是當用戶或者瀏覽器自身執行的某種動作,諸如 click、mouseover等都是事件的名稱,那響應個事件的函數就稱為事件處理程序(事件處理函數、事件句柄)。 事件處理程序的名字都是以on...
閱讀 1442·2023-04-25 19:00
閱讀 4135·2021-11-17 17:00
閱讀 1753·2021-11-11 16:55
閱讀 1511·2021-10-14 09:43
閱讀 3108·2021-09-30 09:58
閱讀 850·2021-09-02 15:11
閱讀 2118·2019-08-30 12:56
閱讀 1399·2019-08-30 11:12