1. 程式人生 > 實用技巧 >DOM事件流與事件物件

DOM事件流與事件物件

DOM事件流與事件物件

1. DOM事件流

事件流描述的是從頁面中接收事件的基礎。事件發生時會在元素節點之間按照特定的順序傳播,這個傳播過程即是DOM事件流

舉個例子,下面是給一個div註冊了點選事件後,事件傳播的過程。

DOM事件流分為三個階段:

  1. 捕獲階段
  2. 當前目標階段
  3. 冒泡階段
  • 事件捕獲:由DOM最頂層節點開始,然後逐級向下傳播到具體的元素接收的過程

  • 事件冒泡:事件開始時由具體的元素接收,然後逐級向上傳播到DOM最頂層節點的過程

由此可知,事件捕獲和事件冒泡是一個順序相反的過程。

注意:

  1. js程式碼中只能執行捕獲或者冒泡其中一個階段
  2. onclick和attachEvent只能得到冒泡階段
  3. 實際開發中更關注事件冒泡
  4. 有些事件是沒有冒泡的,比如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() 該方法阻止冒泡(標準)

注:

  1. e.target與this的區別:
    • e.target返回的是觸發事件的物件,this返回的是繫結事件的物件
    • e.target是點選了哪個元素,就返回哪個元素;this是哪個元素繫結了這個點選事件,就返回哪個元素

2.4 事件物件相容性的解決

事件物件本身的獲取存在相容性問題:

  1. 標準瀏覽器中是瀏覽器給方法傳遞的引數,只需要定義形參e就可以獲取到
  2. 在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() {
    
})
  1. 禁止滑鼠右鍵選單contextmenu

    contextmenu主要控制應該何時顯示上下文選單,主要用於取消預設的上下文選單。

    document.addEventListener('contextmenu', function(e) {
        e.preventDefault();
    })
    
  2. 禁止滑鼠選中(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等等)

注:

  1. 如果使用方法監聽註冊方式時不需要加on
  2. onkeydown和onkeyup不區分大小寫,onkeypress區分大小寫

7.1 鍵盤事件物件

屬性 說明
keyCode 返回該鍵的ASCII值

注:keyCode屬性可以區分大小寫(由返回的ASCII碼不同可以看出),可以和onkeyup、onkeydown搭配使用。