我們知道,在主流的瀏覽器裡面繫結事件處理程式和解綁分別是:
繫結:addEventListener(eventType, handler, useCapture);
解綁:removeEventListener(eventType, handler, useCapture);
eventType: 事件的名字,string型別,例如‘click’
handler: 事件處理程式,function型別
useCapture:
如果為true, handler在事件捕獲階段執行
如果為false, handler在事件冒泡階段執行
然而IE9之前,IE的事件處理程式是不一樣,首先看看它的兩個方法:
繫結:attachEvent(eventNameWithOn, handler)
解綁:detachEvent(eventNameWithOn, handler)
eventNameWithOn: 事件的名字,並且前面有‘on’
handler: 事件處理程式
IE的事件處理程式除了從方法名字的不同,還有其他的一些不同,來做一個總結:
1: 引數不同
IE版本沒有useCapture這個引數,因為IE只支援冒泡,所以也沒必要給出這個引數了。也可以理解為在attachEvent()和detachEvent()內useCapture為false.
2: this不同
在非IE的其他瀏覽器中,我們傳遞給事件處理程式(handler)的this是事件目標元素(也就是我們的target);但是,IE的this卻是Window
3: Event物件不同
在非IE的其他瀏覽器中,我們會把Event物件傳給我們的事件處理程式(handler),但是IE卻沒有,而是作為一個屬性繫結在了Window上
4: 在非IE的其他瀏覽器中和IE的Event例項中的內容是不一樣的
1: 事件源: target -> srcElement(IE)
2: 阻止瀏覽器預設行為:preventDefault -> returnValue = false(IE)
3: 阻止事件冒泡: stopPropagation -> cancelBubble = true
其實還有很多的不同,以上三點算是比較重要又普遍的
所以如果我們要實現一個跨瀏覽器的事件代理,就要處理IE的那些不同。假設我們有這樣的一段HTML:
<ul class='bookList'>
<li class='bookItem'>book 1</li>
<li class='bookItem'>book 2</li>
<li class='bookItem'>book 3</li>
<li class='bookItem'>book 4</li>
</ul>
我們想要實現一個效果,點選'<li>'的時候,彈出此'<li>'內的文字。我們採用代理的方式,利用時間的冒泡把事件繫結到‘<ul>’上,而不是每一個‘<li>’上面:
var bookList = document.getElementsByClassName('bookList')[0];
if(document.addEventListener){
bookList.addEventListener('click', function(event){
var target = getTarget(event);
if(target.nodeName === 'LI'){
alert(target.innerHTML);
}
})
}
if(document.attachEvent){
bookList.attachEvent('click', function(event){
var target = getTarget(event);
if(target.nodeName === 'LI'){
alert(target.innerHTML);
}
})
}
function getTarget(event){
var event = event || window.event;
var target = event.target || event.srcElement;
return target;
}