javascript
JavaScript — 浏览器事件、冒泡和捕获、事件委托
目錄
一、瀏覽器事件
1.事件處理程序?
2.addEventListener?
(1).添加處理程序
(2).移除處理程序
3.事件對象
4.對象處理程序handleEvent?
二、冒泡和捕獲
1.冒泡
2.event.target
3.停止冒泡
4.捕獲
三、事件委托?
一、瀏覽器事件
事件?是某事發生的信號。所有的 DOM 節點都生成這樣的信號(但事件不僅限于 DOM)。
以下列舉出了一些DOM事件
鼠標事件:
- click?—— 當鼠標點擊一個元素時(觸摸屏設備會在點擊時生成)。
- contextmenu?—— 當鼠標右鍵點擊一個元素時。
- mouseover?/?mouseout?—— 當鼠標指針移入/離開一個元素時。
- mousedown?/?mouseup?—— 當在元素上按下/釋放鼠標按鈕時。
- mousemove?—— 當鼠標移動時。
鍵盤事件:
- keydown?和?keyup?—— 當按下和松開一個按鍵時。
表單(form)元素事件:
- submit?—— 當訪問者提交了一個?<form>?時。
- focus?—— 當訪問者聚焦于一個元素時,例如聚焦于一個?<input>。
Document 事件:
- DOMContentLoaded?—— 當 HTML 的加載和處理均完成,DOM 被完全構建完成時。
CSS 事件:
- transitionend?—— 當一個 CSS 動畫完成時。
1.事件處理程序?
????????為了對事件作出響應,我們可以分配一個?處理程序(handler)—— 一個在事件發生時運行的函數。處理程序是在發生用戶行為(action)時運行 JavaScript 代碼的一種方式。
(1).HTML特性
處理程序可以設置在 HTML 中名為?on<event>?的特性(attribute)中。HTML 特性名是大小寫不敏感的。
舉個例子:
<input value="Click me" onclick="alert('Click!')" type="button">?(2).DOM屬性
可以使用 DOM 屬性(property)on<event>?來分配處理程序。DOM 屬性是大小寫敏感的。
舉個例子:
<input id="elem" type="button" value="Click me"> <script>elem.onclick = function() {alert('Thank you');}; </script>因為這里只有一個?onclick?屬性,所以我們無法分配更多事件處理程序。
處理程序中的?this?的值是對應的元素。就是處理程序所在的那個元素。
2.addEventListener?
上述分配處理程序的方式的根本問題是 —— 我們不能為一個事件分配多個處理程序。
addEventListener 和 removeEventListener
(1).添加處理程序
element.addEventListener(event, handler[, options]);?
event:事件名,例如:"click"。
handler:處理程序。
options:具有以下屬性的附加可選對象:
- once:如果為?true,那么會在被觸發后自動刪除監聽器。
- capture:事件處理的階段。由于歷史原因,options?也可以是?false/true,它與?{capture: false/true}?相同。
- passive:如果為?true,那么處理程序將不會調用?preventDefault()。
(2).移除處理程序
element.removeEventListener(event, handler[, options]);
要移除處理程序,我們需要傳入與分配的函數完全相同的函數。如下:
function handler() {alert( 'Thanks!' ); }input.addEventListener("click", handler); // .... input.removeEventListener("click", handler);?該方式是錯誤的:
elem.addEventListener( "click" , () => alert('Thanks!')); // .... elem.removeEventListener( "click", () => alert('Thanks!'));請注意 —— 如果我們不將函數存儲在一個變量中,那么我們就無法移除它。由?addEventListener?分配的處理程序將無法被“讀回”。
多次調用?addEventListener?允許添加多個處理程序 !!!
3.事件對象
????????當事件響應函數被觸發時,瀏覽器每次都會將一個事件對象作為實參傳遞進響應函數,
????????在事件對象中封裝了當前事件相關的一切信息,比如:鼠標的坐標、鍵盤被哪個按鍵按下,鼠標滾輪滾動的方向。
event?對象的一些屬性:
event.type:事件類型,這里是?"click"。
event.currentTarget:處理事件的元素。這與?this?相同,除非處理程序是一個箭頭函數,或者它的?this?被綁定到了其他東西上,之后我們就可以從?event.currentTarget?獲取元素了。
event.clientX / event.clientY:指針事件(pointer event)的指針的窗口相對坐標。
4.對象處理程序handleEvent?
可以使用?addEventListener?將一個對象分配為事件處理程序。當事件發生時,就會調用該對象的?handleEvent?方法。
舉個例子:
<button id="elem">Click me</button><script>let obj = {handleEvent(event) {alert(event.type + " at " + event.currentTarget);}};elem.addEventListener('click', obj); </script>二、冒泡和捕獲
DOM事件標準描述了事件傳播的 3 個階段:
事件傳播過程的示意圖如下:?
?
?
?1.冒泡
????????所謂的冒泡指的就是事件的向上傳導,當后代元素上的事件被觸發時,其祖先元素的相同事件也會被觸發
????????在開發中大部分冒泡都是有用的,如果不希望發生事件,冒泡可以通過事件對象來取消冒泡
如下圖:
?點擊內部的?<p>?會首先運行?onclick:
?
?這個過程被稱為“冒泡(bubbling)”,因為事件從內部元素“冒泡”到所有父級,就像在水里的氣泡一樣。
2.event.target
????????父元素上的處理程序始終可以獲取事件實際發生位置的詳細信息。
????????引發事件的那個嵌套層級最深的元素被稱為目標元素,可以通過?event.target?訪問。
3.停止冒泡
????????冒泡事件從目標元素開始向上冒泡。通常,它會一直上升到?<html>,然后再到?document?對象,有些事件甚至會到達?window,它們會調用路徑上所有的處理程序。
????????但是任意處理程序都可以決定事件已經被完全處理,并停止冒泡。
????????用于停止冒泡的方法是?event.stopPropagation()。
????????如果一個元素在一個事件上有多個處理程序,即使其中一個停止冒泡,其他處理程序仍會執行。
????????換句話說,event.stopPropagation()?停止向上移動,但是當前元素上的其他處理程序都會繼續運行。
????????有一個?event.stopImmediatePropagation()?方法,可以用于停止冒泡,并阻止當前元素上的處理程序運行。使用該方法之后,其他處理程序就不會被執行。
4.捕獲
? ? ? ?捕獲階段很少使用,在事件傳播圖中,點擊?<td>,事件首先通過祖先鏈向下到達元素(捕獲階段),然后到達目標(目標階段),最后上升(冒泡階段),在途中調用處理程序。
?
三、事件委托?
????????事件的委托是指將事件統一綁定給元素的共同的祖先元素,這樣當后代元素上的事件觸發時,會一直冒泡到祖先元素,從而通過祖先元素的響應函數來處理事件。
????????事件委派是利用了冒泡,通過委派可以減少事件綁定的次數,提高程序的性能
舉個例子:
<head><meta charset="UTF-8"><title>Document</title><script>window.onload = function () {let btn01 = document.getElementById("btn01");let ul = document.getElementById("ul")btn01.onclick = function () {//創建一個lilet li = document.createElement("li")let a = document.createElement("a")let text = document.createTextNode("超鏈接")a.append(text)li.append(a)ul.append(li)a.href = "#"a.className = "link"}//希望只綁定一次事件,即可應用到多個元素上,即使元素是后來添加的//可以嘗試將其綁定給元素的共同的祖先元素ul.onclick = function () {//如果觸發的對象是我們期望的元素,則執行,否則不執行if (event.target.className == "link") {alert("我是a的單擊響應函數")}}}</script> </head><body><button id="btn01">添加超鏈接</button><ul id="ul"><li><a href="javascript:;" class="link">超鏈接一</a></li><li><a href="javascript:;" class="link">超鏈接二</a></li><li><a href="javascript:;" class="link">超鏈接三</a></li></ul> </body>? ? ? ? 該例中,在ul上綁定事件,觸發對象后判斷是否是目標對象,是則執行,不是則不執行。?
?
總結
以上是生活随笔為你收集整理的JavaScript — 浏览器事件、冒泡和捕获、事件委托的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SteamAPI
- 下一篇: 万能PDF格式转换器下载