本文是學習中傳思客在慕課網開的課程《前端跳槽面試必備技巧》的學習筆記。課程地址:https://coding.imooc.com/class/evaluation/129.html#Anchor。
本文將從以下幾個方面介紹DOM事件:
- 基本概念:DOM事件的級別
- DOM事件模型,事件流
- 描述DOM事件捕獲的具體流程
- Event對象的常見應用
- 自定義事件
DOM事件的級別
//DOM0 element.onclick = function(){} //DOM2 element.addEventListener('click',function(){},false) //DOM3 element.addEventListener('onmouseover',function(){},false)
先解答一個小疑問:為啥沒有DOM1級事件呢?
因為在1級DOM標准中沒有定義與事件有關的內容,所以事件的級別是沒有DOM1的。
下面簡單介紹dom0,2,3的區別
0級是最早的,而且目前所有的瀏覽器仍支持0級DOM模型。缺點是一個事件的處理程序只能對應一個函數
刪除DOM0事件處理程序,只要將對應事件屬性置為null即可。
在2級模型中可以為特定對象的事件注冊多個事件監聽。
2級事件的刪除
removeEventListener("click",function(){},false);
3級事件的操作方式和2級事件是一樣的。DOM3級事件模塊在DOM2級事件的基礎上重新定義了這些事件,也添加了一些新事件。包括IE9在內的主流瀏覽器都支持DOM2級事件,IE9也支持DOM3級事件。dom對以下事件做了改動
- UI事件
- 焦點事件
- 鼠標事件
- 滾輪事件
- 文本事件
- 鍵盤事件
- 合成事件
- 變動事件
關於dom事件級別更多相關內容,推薦大家一篇文章,寫的挺詳細的。傳送門
另:dom3中還定義了自定義事件,在文章下面中會講到
事件模型 事件流
定義:
1.事件流
描述的是從頁面中接收事件的順序,也可理解為事件在頁面中傳播的順序。
2.事件
就是用戶或瀏覽器自身執行的某種動作。諸如click(點擊)、load(加載)、mouseover(鼠標懸停)。
3.事件處理程序
響應某個事件的函數就叫事件處理程序(或事件偵聽器)
這兩個事件流分別的是IE公司和netspace公司提出來的,冒泡事件流支持的瀏覽器更多。
事件捕獲階段:事件從最上一級標簽開始往下查找,直到捕獲到事件目標(target)。
事件冒泡階段:事件從事件目標(target)開始,往上冒泡直到頁面的最上一級標簽。
描述DOM事件捕獲的具體流程
事件捕獲示意圖
和事件冒泡相反,事件捕獲是自上而下執行,我們只需要將addEventListener的第三個參數改為true就行。
下面通過代碼示例來感受一下
<body> <div id="ev"> <style media="screen"> #ev{ width: 300px; height: 100px; background: red; color: #fff; text-align: center; line-height: 100px; } </style> 目標元素 </div> <script type="text/javascript"> var ev = document.getElementById('ev'); ev.addEventListener('click', function (e) { console.log('ev captrue'); }, true); window.addEventListener('click', function (e) { console.log('window captrue'); }, true); document.addEventListener('click', function (e) { console.log('document captrue'); }, true); document.documentElement.addEventListener('click', function (e) { console.log('html captrue'); }, true); document.body.addEventListener('click', function (e) { console.log('body captrue'); }, true); </script> </body>
輸出結果
這個例子很好的驗證了捕獲是由上到下的。
注意:最上層的是window而不是html。
Event對象的常見應用
event對象的方法是有很多的,像鼠標位置鍵盤key值的這樣的就不多說了,下面介紹幾個我認為比較重要的。
1.event.preventDefault()
此方法用來阻止默認的事件,比如阻止a標簽的跳轉。用法:
dom.addEventListener('click',function(event){ event.preventDefault() },false)
2.event.stopPropagation()
阻止冒泡;讓事件停留在當前dom而不會向上傳遞,
3.event.stopImmediatePropagation()
stopImmediatePropagation()
函數用於阻止剩余的事件處理函數的執行,並防止當前事件在DOM樹上冒泡。
4.event.target
target 事件屬性可返回事件的目標節點(觸發該事件的節點),如生成事件的元素、文檔或窗口。
來一段代碼
<html> <head> <script type="text/javascript"> function getEventTrigger(event) { x=event.target; alert("The id of the triggered element: " + x.id); } </script> </head> <body > <p id="p1" onmousedown="getEventTrigger(event)"> Click on this paragraph. An alert box will show which element triggered the event.</p> </body> </html>
輸出結果
5.event.currentTarget
currentTarget 事件屬性返回其監聽器觸發事件的節點,即當前處理該事件的元素、文檔或窗口。
在捕獲和起泡階段,該屬性是非常有用的,因為在這兩個節點,它不同於 target 屬性。
與event.target的區別
event.currentTarget指向事件所綁定的元素,而event.target始終指向事件發生時的元素
代碼:
<html> <head> <script type="text/javascript"> function getEventTrigger(event) { x=event.currentTarget; alert("The id of the triggered element: " + x.id); } </script> </head> <body > <p id="p1" onmousedown="getEventTrigger(event)"> Click on this paragraph. An alert box will show which element triggered the event.</p> </body> </html>
結果
自定義事件
這部分直接通過代碼來感受一下吧
var eve = new Event('test');
ev.addEventListener('test', function () {
console.log('test dispatch');
});
setTimeout(function () {
ev.dispatchEvent(eve);
}, 1000)
一秒鍾后,控制台打印