前言
- 從事多年開發(fā),也經(jīng)常性的給元素添加事件,但是最多的就是
click事件,回想起來很多事件都沒有仔細的用過,也沒有添加過屬性。 - 所以,最近整理一些javascript原生的事件,希望能夠和大家一起學(xué)習(xí)。
基礎(chǔ):事件的三個階段
- 1?? 事件捕獲階段
- 2?? 執(zhí)行階段(執(zhí)行當(dāng)前元素的注冊事件)
- 3?? 事件冒泡階段。本節(jié)通過一個示例,對三個階段加以總結(jié)
1.添加事件監(jiān)聽 addEventListener
addEventListener(type,listener,userCapture)可以向window或者想要添加監(jiān)聽的dom元素添加事件監(jiān)聽
- type:事件名稱 click mouseover mouseout
- listener:事件注冊函數(shù)
- userCapture:可選,bool類型,默認為false
示例:頁面中嵌套三個盒子,box1,box2,box3(從外到內(nèi),依次是紅色,綠色,藍色),給三個盒子都注冊點擊事件,輸出三個盒子的id,

當(dāng)userCapture屬性為false時候,點擊藍色盒子時,結(jié)果如下:

當(dāng)
userCapture屬性為true時候,點擊藍色盒子時,結(jié)果如下:

分析:
當(dāng)userCapture屬性為false時候,從里往外執(zhí)行,這種執(zhí)行效果稱為事件冒泡,就像一個氣泡從水里最深處往外冒一樣。事件冒泡從里面往外面泡, box3-->box2-->box1.
給addEventListener的userCapture屬性賦值為true,選執(zhí)行最外層的box1,再執(zhí)行box2,box3,這種從外向里的過程是事件捕獲。
結(jié)論:
在上述代碼中,給addEventListener的userCapture屬性賦值為true,此時事件階段是事件捕獲階段。
當(dāng)addEventListener的userCapture屬性賦值為false時,此時事件階段是事件冒泡階段。
只要是某個元素的監(jiān)聽被觸發(fā)了,都會經(jīng)歷事件的三個階段,只不過監(jiān)聽的位置不一樣而已。
相關(guān)代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box1 {
width: 200px;
height: 200px;
background-color: red;
}
#box2 {
width: 150px;
height: 150px;
background-color: green;
}
#box3 {
width: 90px;
height: 90px;
background-color: blue;
}
</style>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
</body>
<script>
let box1 = document.getElementById('box1')
let box2 = document.getElementById('box2')
let box3 = document.getElementById('box3')
var boxs = [box1, box2, box3];
for (var i = 0; i < boxs.length; i++) {
boxs[i].addEventListener('click', outPut, true); //設(shè)置觸發(fā)階段
}
//點擊事件函數(shù)
function outPut(event) {
console.log(event,'===event');
console.log(this.id);
}
</script>
</html>
1.2事件冒泡的好處就是能夠進行事件委托
2. event對象常用的屬性和方法
addEventListener(type,listener,userCapture) 在增加監(jiān)聽的時候,listener參數(shù)是可以獲取到event參數(shù)的,里面除了包含基本的信息之外,還有很多的屬性,那這些屬性都有什么意思呢?

2.1 Event屬性說明
| 屬性名 | 值類型 | 描述 |
|---|---|---|
| altKey | Boolean | 觸發(fā)事件時是否按下alt鍵【可做組合鍵事件】 |
| bubbles | Boolean | 指的是該事件是否冒泡。和事件處理機制無關(guān)。 |
| buttom | Number | 返回當(dāng)事件被觸發(fā)時,哪個鼠標(biāo)按鈕被點擊【0 指定鼠標(biāo)左鍵。2 指定鼠標(biāo)右鍵。4指定鼠標(biāo)中鍵】 |
| buttoms | Number | 表示一個數(shù)字,它表示在鼠標(biāo)事件中哪些按鈕被按下【1 指定鼠標(biāo)左鍵。2 指定鼠標(biāo)中鍵。4 指定鼠標(biāo)右鍵?!?/td> |
這些值可以組合使用,例如同時按下左鍵和右鍵會得到 3(1 + 2),同時按下左鍵、右鍵和滾輪按鈕會得到 7(1 + 2 + 4)。??示例:3.1.1
|
||
| cancelable | Boolean | 用于表示事件是否可以被取消。??示例:3.1.2
|
| clientX | Number | 表示鼠標(biāo)事件發(fā)生時的鼠標(biāo)指針相對于瀏覽器窗口(視口)左上角的水平坐標(biāo)位置。 |
| clientY | Number | 表示鼠標(biāo)事件發(fā)生時的鼠標(biāo)指針相對于瀏覽器窗口(視口)左上角的垂直坐標(biāo)位置。 |
| ctrlKey | Boolean | 觸發(fā)事件時是否按下ctrl鍵【可做組合鍵事件】 |
| currentTarget | any | 用于表示事件當(dāng)前正在被處理的元素(可以理解為觸發(fā)事件的元素的父級元素,事件委托相關(guān)。 而觸發(fā)事件的元素屬性是event.target)。 |
| defaultPrevented | Boolean | 表示事件的默認行為是否被取消 該屬性是只讀屬性,不能直接修改其值。它僅用于指示事件的默認行為是否被取消 ??示例:3.1.3
|
| detail | Number | 表示與鼠標(biāo)事件或滾輪事件相關(guān)的附加信息,【1.對于點擊事件,則表示連續(xù)點擊的次數(shù)】【2.對于滾動事件來說則表示鼠標(biāo)滾輪事件的滾動量,通常表示為正值或負值】??示例:3.1.4
|
| deltaMode | Number | deltaMode 是 WheelEvent 對象的一個屬性,在 JavaScript 中用于表示鼠標(biāo)滾輪事件中滾動量的單位。 |
| deltaX | Number | WheelEvent 對象的一個屬性,在 JavaScript 中用于表示鼠標(biāo)滾輪事件中水平方向上的滾動量。 |
| deltaY | Number | WheelEvent 對象的一個屬性,在 JavaScript 中用于表示鼠標(biāo)滾輪事件中垂直方向上的滾動量。 |
| deltaZ | Number | WheelEvent 對象的一個屬性,在 JavaScript 中用于表示鼠標(biāo)滾輪事件中Z軸方向上的滾動量 |
| eventPhase | Number | 表示事件當(dāng)前所處的階段?!?表示事件尚未觸發(fā),1表示事件正在處于事件捕獲階段。2示事件正在處于事件捕獲階段。3.表示事件正在處于事件冒泡階段?!?/td> |
| isTrusted | Boolean | 表示事件是否由用戶操作觸發(fā),并且是否可以被認為是可信的 |
| metaKey | Boolean | 用于表示在觸發(fā)事件時是否按下了操作系統(tǒng)特定的 Meta 鍵(如 Command 鍵或 Windows 鍵)。【在 macOS 系統(tǒng)中,Meta 鍵是 Command 鍵;在 Windows 系統(tǒng)中,Meta 鍵是 Windows 鍵】 |
| movementX | Number | 只讀屬性,用于獲取鼠標(biāo)從上一個 mousemove 事件到當(dāng)前 mousemove 事件中鼠標(biāo)在水平方向上的移動距離。這個屬性可以在mousemove事件的事件處理函數(shù)中通過事件對象(比如 event 或e)來訪問
|
| movementY | Number | 只讀屬性,用于獲取鼠標(biāo)從上一個 mousemove 事件到當(dāng)前 mousemove 事件中鼠標(biāo)在垂直方向上的移動距離。這個屬性可以在mousemove事件的事件處理函數(shù)中通過事件對象(比如 event 或e)來訪問
|
| pageX | Number | 鼠標(biāo)在頁面水平坐標(biāo)位置上的位置,從頁面左上角開始,即是以頁面為參考點,不隨滑動條移動而變化, |
| pageY | Number | 鼠標(biāo)在頁面垂直坐標(biāo)位置上的位置,從頁面左上角開始,即是以頁面為參考點,不隨滑動條移動而變化, |
| relatedTarget | any |
relatedTarget是一個事件屬性,用于獲取與事件相關(guān)的目標(biāo)元素或移出的元素。它主要用于鼠標(biāo)事件(如 mouseover 和 mouseout)和焦點事件(如 focusin和focusout) |
| screenX | Number | 鼠標(biāo)相對于用戶顯示器屏幕左上角的X軸的位置。??示例:3.1.5
|
| screenY | Number | 鼠標(biāo)相對于用戶顯示器屏幕左上角的Y軸的位置。 |
| shiftKey | Boolean | 觸發(fā)事件時是否按下shift鍵【可做組合鍵事件】 |
| target | any | 該事件被傳送的對象。??詳情查看表target詳解
|
| timeStamp | Number | 用于獲取事件發(fā)生的時間戳。時間戳表示從特定的參考點(通常是1970年1月1日UTC時間午夜)開始計算的毫秒數(shù)。 |
| type | String | 監(jiān)聽事件的類型 |
| view | Wiindow | 用于獲取觸發(fā)事件的窗口的相關(guān)信息。 |
| getModifierState | Function | 是 鍵盤事件對象的一個方法,在 JavaScript 中用于檢查鍵盤事件中的修改鍵(如 Shift、Ctrl、Alt 和 Meta/Command 鍵)的狀態(tài)。??示例:3.1.9
|
| isDefaultPrevented | Function | 用于檢查事件是否調(diào)用了preventDefault()方法來阻止默認行為。調(diào)用event.isDefaultPrevented()會返回一個布爾值,如果默認行為已被阻止,則返回true,否則返回false。??示例:3.1.10
|
| isPropagationStopped | Function | 用于檢查事件是否已經(jīng)停止了事件傳播。??示例:3.1.11
|
2.2 target 屬性說明
- target 事件屬性可返回事件的目標(biāo)節(jié)點(觸發(fā)該事件的節(jié)點),如生成事件的元素、文檔或窗口
- target 內(nèi)是目標(biāo)節(jié)點的屬性有很多,這里截取最常用的幾個
| 屬性名 | 值類型 | 描述 |
|---|---|---|
| nodeName | String | 獲取事件觸發(fā)元素的標(biāo)簽 |
| id | String | 觸發(fā)元素的id名稱 |
| className | string | 觸發(fā)元素的類名 |
| innerHTML | String | 觸發(fā)元素的內(nèi)容,包括子元素的dom |
| innerText | String | 觸發(fā)元素內(nèi)部的text文本 |
| baseURI | String | 觸發(fā)元素當(dāng)前的url路徑 |
3 此處放置event屬性的示例
3.1 屬性示例
3.1.1 buttoms 屬性示例
element.addEventListener('mousedown', function(event) {
if (event.buttons === 1) {
console.log("左鍵被按下了");
} else if (event.buttons === 2) {
console.log("右鍵被按下了");
} else if (event.buttons === 4) {
console.log("中間按鈕被按下了");
} else if (event.buttons === 3) {
console.log("左鍵和右鍵被按下了");
} else if (event.buttons === 7) {
console.log("左鍵、右鍵和中間按鈕被按下了");
}
});
3.1.2 cancelable 示例
如果 cancelable 屬性為 true,則事件可以被取消,即可以調(diào)用 event.preventDefault() 方法取消默認行為。取消事件的默認行為意味著阻止瀏覽器執(zhí)行與事件相關(guān)的默認操作。例如,阻止表單的提交、禁止鏈接的跳轉(zhuǎn)等。
如果 cancelable 屬性為 false,則事件不可被取消,無法調(diào)用 event.preventDefault() 方法。
element.addEventListener('click', function(event) {
if (event.cancelable) {
event.preventDefault(); // 取消事件的默認行為
console.log("事件已被取消");
}
});
3.1.3 defaultPrevented示例
當(dāng)調(diào)用 event.preventDefault()方法取消事件的默認行為時,defaultPrevented 屬性的值將變?yōu)?code>true。如果事件的默認行為沒有被取消或事件不支持取消默認行為,defaultPrevented屬性的值將為 false。
element.addEventListener('click', function(event) {
event.preventDefault(); // 取消事件的默認行為
console.log("事件的默認行為已被取消:" + event.defaultPrevented);
});
3.1.4 detail 示例
element.addEventListener('click', function(event) {
console.log("點擊事件發(fā)生的次數(shù):", event.detail);
});
element.addEventListener('wheel', function(event) {
console.log("滾動量:", event.detail);
});
當(dāng)用戶點擊元素時,會輸出點擊事件發(fā)生的次數(shù),以及當(dāng)用戶滾動鼠標(biāo)滾輪時,會輸出滾動的量(正向滾動為正值,負向滾動為負值)。
需要注意的是,`detail` 屬性在一些瀏覽器中已經(jīng)被廢棄,可以使用 `event.deltaX` 或 `event.deltaY` 替代,具體取決于事件類型。
3.1.5 screenX示例
注意:當(dāng)你的瀏覽器窗口和你的屏幕大小一樣大的時候,pageX 、screenX、clientX的值是一樣大的,但是,當(dāng)你改變?yōu)g覽器窗口的大小改變?yōu)g覽器位置的時候, screenX的值就會有所變變化

3.1.6 cancelable 示例
3.1.9 getModifierState示例
getModifierState 方法接受一個參數(shù),即指定要檢查的修改鍵的字符串表示形式。常見的參數(shù)值包括:
- Shift:用于檢查 Shift 鍵的狀態(tài)。
- Control:用于檢查 Ctrl 鍵的狀態(tài)。
- Alt:用于檢查 Alt 鍵的狀態(tài)。
- Meta 或 Command:用于檢查 Meta/Command 鍵(通常是 Windows 鍵或 Command 鍵)的狀態(tài)。
document.addEventListener('keydown', function(event) {
if (event.getModifierState('Shift')) {
console.log("Shift 鍵按下");
}
if (event.getModifierState('Control')) {
console.log("Ctrl 鍵按下");
}
if (event.getModifierState('Alt')) {
console.log("Alt 鍵按下");
}
if (event.getModifierState('Meta') || event.getModifierState('Command')) {
console.log("Meta/Command 鍵按下");
}
});
- 在上面的示例中,當(dāng)用戶按下鍵盤上的某個鍵時,
getModifierState方法被用來檢查修改鍵的狀態(tài)。對于處于按下狀態(tài)的修改鍵,相應(yīng)的消息將被輸出到控制臺。 - 需要注意的是,不同的瀏覽器可能在檢測鍵盤事件和修改鍵狀態(tài)時有所不同,因此在使用
getModifierState方法時,最好先進行測試和兼容性檢查。
3.1.10 isDefaultPrevented 方法示例:
document.getElementById('myLink').addEventListener('click', function(event) {
event.preventDefault();
console.log(event.isDefaultPrevented()); // true
});
- 在這個示例中,當(dāng)點擊具有ID為
myLink的元素時,事件處理程序會調(diào)用preventDefault()方法來阻止默認的點擊行為。然后,isDefaultPrevented()方法被調(diào)用,并且返回true,表示默認行為已被阻止。
3.1.11 isPropagationStopped 方法示例:
- 在JavaScript中,事件傳播包括捕獲階段、目標(biāo)階段和冒泡階段。調(diào)用
event.stopPropagation()方法可以停止事件在這些階段的傳播。isPropagationStopped方法可用于檢查事件是否已經(jīng)停止了傳播。
document.getElementById('myDiv').addEventListener('click', function(event) {
event.stopPropagation();
console.log(event.isPropagationStopped()); // true
});
document.body.addEventListener('click', function(event) {
console.log(event.isPropagationStopped()); // false
});