1.attachEvent與addEventListener的區別
- 支持的瀏覽器不同。
attachEvent在IE9以下的版本中受到支持。其它的都支持addEventListener。 - 參數不同。
addEventListener第三個參數可以指定是否捕獲,而attachEvent不支持捕獲。 - 事件名不同。
attachEvent第一個參數事件名前要加on,比如el.attachEvent('onclick', handleClick)。 this不同。本文的將重點解釋
2.attachEvent方式的事件綁定
attachEvent的this總是Window。例如:
el.attachEvent('onclick', function(){
alert(this);
});
執行后會彈出對話框:[object Window]。
3.addEventListener方式的事件綁定
addEventListener的this總是當前正在處理事件的那個DOM對象。 DOM Level 2 Event Model中提到,事件處理包括捕獲階段、目標階段和冒泡階段 。如下圖:

事件當前正在流過哪個元素,this便指向哪個元素。比如對於兩級的DOM:
<div id="l1"> <div id="l2"></div> </div> <script type="text/javascript"> var l1 = document.getElementById('l1'), l2 = document.getElementById('l2'); l1.addEventListener('click', function () { console.log('l1 capture', this); }, true); l1.addEventListener('click', function () { console.log('l1 bubbling', this); }); l2.addEventListener('click', function () { console.log('l2 target', this); }); </script>
點擊div#l2后控制台輸出為:
l1 capture <div id="l1">…</div> l2 target <div id="l2"></div> l1 bubbling <div id="l1">…</div>
4.糾正attachevent
Event.addEvent = function(target,eventType,handle){ target.attachEvent('on'+eventType,function(){ handle.call(currentTarget,arguments);//改變this指向 }); }
這里使用了currentTarget,我們再來順着分析一下target與currentTarget。
addEventListener的事件處理函數中this不一定指向事實上被點擊的元素, 但事件處理函數的參數Event對象提供了target和currentTarget屬性來區分這當前對象與目標對象。 我們可以把它們都全部輸出:
l1.addEventListener('click', function (e) {
console.log('l1 capture', this, e.currentTarget, e.target);
}, true);
l2.addEventListener('click', function (e) {
console.log('l2 target', this, e.currentTarget, e.target);
});
l2.addEventListener('click', function (e) {
console.log('l2 target, invalid capture', this, e.currentTarget, e.target);
}, true);
結果是:
l1 capture <div id="l1">…</div> <div id="l1">…</div> <div id="l2"></div> l2 target <div id="l2"></div> <div id="l2"></div> <div id="l2"></div> l1 bubbling <div id="l1">…</div> <div id="l1">…</div> <div id="l2"></div>
可見currentTarget總是和this相同,而target指向事實上被點擊的目標DOM對象。
5.補充:onclick在HTML和腳本中this指向的區別
腳本設置onclick方式的事件綁定
在javascript中設置DOM對象的onclick屬性,this總是指向被設置的DOM元素。例如:
document .getElementById('l1') .onclick = function(){ console.log(this); };
點擊div#l1后控制台輸出為:
<div id="l1">...</div>
HTML中設置onclick方式的事件綁定
在HTML中設置onclick屬性相當於讓Window來調用該處理函數,於是this總是Window。例如:
<div onclick="clickHandler()"></div> <script> function clickHandler(){ console.log(this); } </script>
點擊這個div后的控制台輸出為:
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
