涵蓋知識點:
1、事件流翎猛,事件捕獲胖翰,事件冒泡概念
2、跨瀏覽器事件兼容解決方案(柯里化函數(shù)提前返回)
3切厘、標準事件對象event及ie事件對象常用屬性
4萨咳、ie中attatchEvent事件處理程序中this指向問題
一、事件流
1.ECMAScript標準事件流
標準事件流分為三個階段:事件捕獲階段迂卢,處于目標階段某弦,事件冒泡階段
下面是一段html代碼:
<html>
<body>
<div>
<button>click me</button>
</div>
</body>
</html>
當(dāng)點擊button時,會觸發(fā)一個click事件而克,觸發(fā)事件會經(jīng)歷三個階段:
1.1.事件捕獲階段
事件捕獲階段的思想是不太具體的節(jié)點先接收到事件靶壮,最具體的節(jié)點最后接收到事件,這個階段做的事情是捕獲事件
此例中事件捕獲傳播順序為:
document, html, body, div, button
1.2.處于目標階段
實際目標接收到事件
1.3.事件冒泡階段
最后一個階段员萍,事件冒泡的順序是從最具體的節(jié)點到最不具體的節(jié)點腾降,這個階段對事件做出響應(yīng)
此例中事件冒泡傳播順序為
button, div, body, html, document
注意:所有的瀏覽器都會將事件冒泡到window對象
注意:雖然DOM事件流規(guī)定不能在事件捕獲階段涉及事件目標,但是ie9以及更高級的瀏覽器支持在事件捕獲階段觸發(fā)事件
2.IE事件流
ie8之前碎绎,ie的事件流只有冒泡階段螃壤,沒有捕獲階段
3.事件執(zhí)行順序
一般事件的執(zhí)行順序是:事件捕獲階段 ==>> 處于目標階段 ==>> 事件冒泡階段 ==>> 事件默認行為
事件默認行為最后執(zhí)行,為阻止事件的默認行為提供了機會
function handler (event) {
const event = event || window.event
if (event.preventDefault) {
event.preventDefault() // 非ie瀏覽器阻止事件默認行為
} else {
event.returnValue = false // ie瀏覽器阻止事件默認行為
}
}
二筋帖、DOM事件
1.DOM0級事件
// 添加事件
el.onclick = function () {
// ...
}
// 刪除事件
el.onclick = null
DOM0級事件在冒泡階段執(zhí)行
2.DOM2級事件
DOM2級事件定義了兩個方法奸晴,用于綁定和刪除事件
1.1 addEventListener
addEventListener(type, handler, useCapture)
params: type // 要添加的事件類型
params: handler // 事件處理程序
params: useCapture // 是否在捕獲階段執(zhí)行
使用addEventListener方法的好處是可以添加多個函數(shù),并按添加順序執(zhí)行
2.2 removeEventListener
用于移除通過addEventListener添加的函數(shù)日麸,移除時的參數(shù)必須與添加的參數(shù)一致
removeEventListener(type, handler, useCapture)
使用addEventListener添加的事件必須通過removeEventListener移除
3.ie事件
ie8及ie8之前的版本不支持addEventListener, ie實現(xiàn)了 attachEvent和detachEvent方法添加和刪除事件
attachEvent(type, handler)
params: type //type需要加on
params: handler // 事件處理程序
需要注意的是:
el.attachEvent('onclick', function () {
console.log(this == window) //這里的this 指向window寄啼,而不是指向el
})
為了避免這個問題,我們需要手動將this指向到el
function addEvent (el, type, handler) {
el.attatchEvent('on' + type, function () {
handler.apply(el, arguments) // 改變this指向
})
}
4.跨瀏覽器的事件處理程序(利用柯里化提前返回的特性實現(xiàn))
// 添加事件
const addEvent = function (el, type, handler, isCapture) {
if (window.addEventListener) {
return function () {
el.addEventListener(type, handler, isCapture)
}
} else if (window.attachEvent) {
return function () {
el.attachEvent('on' + type, handler)
}
}()
// 刪除事件
const removeEvent = function (el, type, handler, isCupture) {
if (window.addEventListener) {
return function () {
el.removeListener(type, handler, isCapture)
}
} else if (window.attachEvent) {
return function () {
el.detachEvent('on' + type, handler)
}
}
}
三代箭、事件對象
瀏覽器會為事件處理程序注入event對象墩划,常用的event對象的屬性有:
type // 事件類型
target // 事件的目標
currentTarget // 事件處理程序正在處理的元素
perventDefault() // 阻止事件默認行為
stopPropagation // 阻止事件冒泡
ie對象獨有的event屬性:
type // 事件類型
srcElement// 事件的目標
cancelBubble (Boolean) // 阻止事件默認行為
returnValue (Boolean) // 阻止事件冒泡