DOM事件流與事件物件
阿新 • • 發佈:2020-11-23
DOM事件流與事件物件
1. DOM事件流
事件流描述的是從頁面中接收事件的基礎。事件發生時會在元素節點之間按照特定的順序傳播,這個傳播過程即是DOM事件流。
舉個例子,下面是給一個div註冊了點選事件後,事件傳播的過程。
DOM事件流分為三個階段:
- 捕獲階段
- 當前目標階段
- 冒泡階段
-
事件捕獲:由DOM最頂層節點開始,然後逐級向下傳播到具體的元素接收的過程
-
事件冒泡:事件開始時由具體的元素接收,然後逐級向上傳播到DOM最頂層節點的過程
由此可知,事件捕獲和事件冒泡是一個順序相反的過程。
注意:
- js程式碼中只能執行捕獲或者冒泡其中一個階段
- onclick和attachEvent只能得到冒泡階段
- 實際開發中更關注事件冒泡
- 有些事件是沒有冒泡的,比如onblur、onmouseleave等
2. 事件物件
2.1 事件物件的理解
eventTarget.onclick = function(event) {} // 這個event就是事件物件
簡單理解為,當事件發生後,跟事件相關的一系列資訊資料的集合都放到這個物件裡面,這個物件就是事件物件event。比如是誰綁定了這個事件;如果是滑鼠觸發事件,會得到滑鼠的相關資訊,如滑鼠游標等等。
2.2 事件物件的使用
// 1. eventTarget.onclick = function(event) { } // 2. eventTarget.addEventListener('click', function(event) { })
當我們註冊事件時,event物件就會被系統自動建立,並依次傳遞給事件監聽器(事件處理函式)。
2.3 事件物件的常見屬性和方法
事件物件屬性方法 | 說明 |
---|---|
e.target | 返回觸發事件的物件(標準) |
e.srcElement | 返回觸發事件的物件(非標準,ie6~8使用) |
e.type | 返回事件的型別。eg.click、mouseover(注意不帶on) |
e.cancelBubble | 阻止冒泡(非標準,ie6~8使用) |
e.returnValue | 阻止預設事件,比如不讓連結跳轉(非標準,ie6~8使用) |
e.preventDefault() | 該方法阻止預設事件,比如不讓連結跳轉(標準) |
e.stopPropagation() | 該方法阻止冒泡(標準) |
注:
- e.target與this的區別:
- e.target返回的是觸發事件的物件,this返回的是繫結事件的物件
- e.target是點選了哪個元素,就返回哪個元素;this是哪個元素繫結了這個點選事件,就返回哪個元素
2.4 事件物件相容性的解決
事件物件本身的獲取存在相容性問題:
- 標準瀏覽器中是瀏覽器給方法傳遞的引數,只需要定義形參e就可以獲取到
- 在ie6~8中,瀏覽器不會給方法傳遞引數,如果需要的話,要到window.event中獲取查詢
// 解決
function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
}
3. 阻止預設行為
點選一個連結就會自動跳轉、點選一個提交按鈕就會自動提交,這些都是預設行為。
a.onclick = function(e) {
e.preventDefault(); // 方法(DOM標準寫法)
e.returnValue; // 屬性,低版本瀏覽器適用,比如ie678
return false; // 沒有相容性問題,但是return後面的程式碼不會執行,而且這種方法只限於傳統的註冊方式
}
4. 阻止事件冒泡
4.1 阻止事件冒泡的兩種方式
事件冒泡:開始時由最具體的元素接收,然後逐級向上傳播到DOM最頂層節點。
// 1.標準寫法
e.stopPropagation();
// 2.非標準寫法,ie678
e.cancleBubble = true;
4.2 阻止事件冒泡相容性的解決
if (e && e.stopPropagation) {
e.stopPropagation();
} else {
window.event.cancleBubble = true;
}
5. 事件委託
原理:不是每個子節點單獨設定事件監聽器,而是事件監聽器設定在其父節點上,然後利用冒泡原理影響設定每個子節點。
利用事件委託,可以提高程式的效能。
<ul>
<li><button>1</button></li>
<li><button>2</button></li>
<li><button>3</button></li>
</ul>
<script>
// 給li的父級節點ul設定事件監聽器,當點選li時,也會彈出hello world彈窗
var ul = document.querySelector('ul');
ul.addEventListener('click', function() {
alert('hello world');
})
</script>
6. 常用的滑鼠事件
6.1 傳統註冊方式
滑鼠事件 | 觸發事件 |
---|---|
onclick | 滑鼠點選左鍵觸發 |
onmouseover | 滑鼠經過觸發 |
onmouseout | 滑鼠離開觸發 |
onfocus | 獲得滑鼠焦點觸發 |
onblur | 失去滑鼠焦點觸發 |
onmousemove | 滑鼠移動觸發 |
onmouseup | 滑鼠彈起觸發 |
onmousedown | 滑鼠按下觸發 |
// 獲取事件源
var eg = document.querySelector('div');
//註冊事件
eg.onclick = function() {
//新增事件處理程式
alert('hello world!');
}
6.2 方法監聽註冊方式
方法監聽方式就是在傳統註冊上去掉on。
document.addEventListener('click', function() {
})
-
禁止滑鼠右鍵選單contextmenu
contextmenu主要控制應該何時顯示上下文選單,主要用於取消預設的上下文選單。
document.addEventListener('contextmenu', function(e) { e.preventDefault(); })
-
禁止滑鼠選中(selectstart 開始選中)
document.addEventListener('selectstart', function(e) { e.preventDefault(); })
6.3 滑鼠事件物件
滑鼠事件物件 | 說明 |
---|---|
e.clientX | 返回滑鼠相對於瀏覽器視窗可視區的X座標 |
e.clientY | 返回滑鼠相對於瀏覽器視窗可視區的Y座標 |
e.pageX | 返回滑鼠相對於文件頁面的X座標 ie9+支援 |
e.pageY | 返回滑鼠相對於文件頁面的Y座標 ie9+支援 |
e.screenX | 返回滑鼠相對於電腦螢幕的X座標 |
e.screenY | 返回滑鼠相對於電腦螢幕的Y座標 |
- client:無論有沒有滾動條,座標都不變
- page:有滾動條的時候,座標會變化
7. 常用的鍵盤事件
鍵盤事件 | 觸發條件 |
---|---|
onkeyup | 某個鍵盤按鍵被鬆開時觸發 |
onkeydown | 某個鍵盤按鍵被按下時觸發 |
onkeypress | 某個鍵盤按鍵被按下時觸發(不識別功能鍵,例如ctrl、shift等等) |
注:
- 如果使用方法監聽註冊方式時不需要加on
- onkeydown和onkeyup不區分大小寫,onkeypress區分大小寫
7.1 鍵盤事件物件
屬性 | 說明 |
---|---|
keyCode | 返回該鍵的ASCII值 |
注:keyCode屬性可以區分大小寫(由返回的ASCII碼不同可以看出),可以和onkeyup、onkeydown搭配使用。