JS event物件:記錄當前事件的狀態

2020-07-16 10:05:11
在 JavaScript 中,event 物件由事件自動建立,記錄了當前事件的狀態,如事件發生的源節點、鍵盤按鍵的響應狀態、滑鼠指標的移動位置、滑鼠按鍵的響應狀態等資訊。event 物件的屬性提供了有關事件的細節,其方法可以控制事件的傳播。

2 級 DOM Events 規範定義了一個標準的事件模型,它被除了 IE 怪異模式以外的所有現代瀏覽器所實現,而 IE 定義了專用的、不相容的模型。簡單比較兩種事件模型如下:
  • 在 DOM 事件模型中,event 物件被傳遞給事件處理常式,但是在 IE 事件事件模型中,它被儲存在 window 物件的 event 屬性中。
  • 在 DOM 事件模型中,Event 型別的各種子介面定義了額外的屬性,它們提供了與特定事件型別相關的細節;在 IE 事件模型中,只有一種型別的 event 物件,它用於所有型別的事件。

下面列出了 2 級 DOM 事件標準定義的 event 物件屬性,如下圖所示。注意,這些屬性都是唯讀屬性。

DOM 事件模型中 event 物件屬性
屬性 說明
bubbles 返回布林值,指示事件是否是冒泡事件型別。如果事件時冒泡型別,則返回 true;否則返回 false
cancelable 返回布林值,指示事件是否可以取消的預設動作。如果使用 preventDefault() 方法可以取消與事件關聯的預設動作,則返回值為 true;否則為 false
currentTarget 返回觸發事件的當前節點,即當前處理該事件的元素、文件或介面。在捕獲和冒泡階段,該屬性時非常有用的,因為在這兩個階段,它不同於 target 屬性
eventPhase 返回事件傳播的當前階段,包括捕獲階段(1)、目標事件階段(2)和冒泡階段(3)
target 返回事件的目標節點(觸發該事件的節點),如生成事件的元素、文件或視窗
timeStamp 返回事件生成的日期和時間
type 返回當前 event 物件表示的事件的名稱。如“submit”、“load”或“click”

下面列出了 2 級 DOM 事件標準定義的 event 物件方法,如下表所示。IE 事件模型不支援這些方法。

DOM 事件模型中 event 物件方法
方法 宣告
initEvent() 初始化新建立的 event 物件的屬性
preventDefault() 通知瀏覽器不要執行與事件關聯的預設動作
stopPropagation() 終止事件在傳播過程的捕獲、目標處理或冒泡階段進一步傳播。呼叫該方法後,該節點上處理該事件的處理常式將被呼叫,但事件不再被分派到其他節點

上表是 Event 型別提供的基本屬性,各個事件子模組也都定義了專用屬性和方法。例如,UIEvent 提供了 view(發生事件的 window 物件)和 detail(事件的詳細資訊)屬性;而 MouseEvent 除了擁有 Event 和 UIEvent 屬性和方法外,也定義了更多實用屬性。

IE 7 及其早期版本,,以及 IE 怪異模式不支援標準的 DOM 事件模型,並且 IE 的 event 物件定義了一組完全不同的屬性,如下表所示:

IE 事件模型中 event 物件屬性
屬性 描述
cancelBubble 如果想在事件處理常式中阻止事件傳播到上級包含物件,必須把該屬性設為 true
fromElement 對於 mouseover 和 mouseout 事件,fromElement 參照移出滑鼠的元素
keyCode 對於 keypress 事件,該屬性宣告了被敲擊的鍵生成的 Unicode 字元碼。對於 keydown 和 keyup 事件,它指定了被敲擊的鍵的虛擬鍵盤碼。虛擬鍵盤碼可能和使用的鍵盤的布局相關
offsetX、offsetY 發生事件的地點在事件源元素的坐標系統中的 x 坐標和 y 坐標
returnValue 如果設定了該屬性,它的值比事件處理常式的返回值優先順序高。把這個屬性設定為 false,可以取消事件發生的源元素的預設動作
srcElement 對於生成事件的 window 物件、document 物件或 element 物件的參照
toElement 對於 mouseover 和 mouseout 事件,該屬性參照移入滑鼠的元素
x、y 事件發生的位置的 x 坐標和 y 坐標,它們相對於用 CSS 定位的最內層包含元素

IE 事件模型並沒有為不同的事件定義繼承型別,因此所有和任何事件的的型別相關的屬性都在上面列表中。

為了相容 IE 和 DOM 兩種事件模型,可以使用下面表示式進行相容。
var event = event || window.event;  //相容不同模型的event物件
上面程式碼右側是一個選擇運算表示式,如果事件處理常式存在 event 實參,則使用 event 形參來傳遞事件資訊;如果不存在 event 引數,則呼叫 window 物件的 event 屬性來獲取事件資訊。把上面表示式放在事件處理常式中即可進行相容。

在以事件驅動為核心的設計模型中,一次只能處理一個事件,由於從來不會並行兩個事件,因此使用全域性變數來儲存事件資訊是一種比較安全的方法。

範例

下面範例演示了如何禁止超連結預設的跳轉行為。
<a href="https://www.baidu.com/" id="a1">禁止超連結跳轉</a>
<script>
    document.getElementById("a1").onclick = function(e) {
        e = e || window.event;  //相容事件物件
        var target = e.target || e.srcElement;  //相容事件目標元素
        if (target.nodeName !== 'A') {  //僅針對超連結起作用
            return;
        }
        if (typeof e.preventDefault === 'function') {  //相容DOM模型
            e.preventDefault();  //禁止預設行為
            e.cancelBubble();  //禁止事件傳播
        } else {  //相容IE型別
            e.returnValue = false;  //禁止預設行為
            e.cancelBubble = true;  //禁止冒泡
        }
    };
</script>