標用準瀏覽器中可以使addEventListener()函數來給DOM元素綁定事件,使用removeEventListener()函數移除事件綁定,而IE6 IE7 IE8不支持addEventListener()和removeEventListener(),只能使用attachEvent()和detachEventListener()方法。IE從IE9開始支持addEventListener和removeEventListener.
addEventListener()和attachEvent()的區別主要有以下幾點:
-
addEventListener(type,handler,capture)有三個參數,其中type是事件名稱,如click,handler是事件處理函數,capture是否使用捕獲,是一個布爾值,一般爲false,這是默認值,所以第三個參數可以不寫
attachEvent('on'+type,handler)有兩個參數,其中type是事件名稱,如click,第一個參數必須是onxxxx,handler是事件處理函數,IE6 IE7 IE8不支持事件捕獲的,只支持事件冒泡。
關於事件冒泡:如果一個元素和它的各層上級素都設置了相同的事件,比如click事件,那麼冒泡是指,當用戶點擊鼠標後,先觸發最底層元素的click事件,然後依次逐層觸發上一級元素的click事件,就像泡泡從水底冒到水面一樣。
而與事件冒泡相反,事件捕獲的順序是,從頁面的根元素開始依次逐層向下級觸發事件。
IE6-8只支持事件冒泡不支持事件捕獲,Google Chrome/Firefox/Safari/Opera等標準瀏覽器支持事件捕獲和事件冒泡。
如果只想在最底層執行事件處理函數,阻止向上級元素冒泡,也就是說如果要阻止事件冒泡,標準瀏覽器可以使用stopPropagation(),IE6 7 8可以使用cancelBubble=true - addEventListener綁定的事件是先綁定先執行,attachEvent綁定的事件是先綁定後執行
- 在IE6 IE7 IE8瀏覽器中,使用了attachEvent或detachEvent後事件處事函數裏面的this指向window對象,而不是事件對象元素,文末有解決方案
-
如果一個事件在綁定以後有解除綁定的需要,可以使用removeEventListener(),參數和addEventListener一樣,IE6 IE7 IE8使用detachEvent函數,參數和attachEvent一樣,注意,想要移除綁定的事件,則綁定事件時不能使用匿名函數,而需要將事件處事函數單獨寫成一個函數。否則無法移除綁定的事件函數,因爲只綁定的事件才能移除,匿名函數和匿名函數是互相不相同的,即使代碼完全一樣,但本質上同一匿名函數的代碼寫兩次就是兩個不同的函數。
下面以addEventListener爲例
-
<a id="xc">點擊</a>
-
<script type="text/javascript">
-
function handler(){
-
alert(this.innerHTML);
-
}
-
var object=document.getElementById('xc');
-
xc.addEventListener('click',handler,false);//添加事件
-
xc.removeEventListener('click',handler,false);//移除事件
-
/*下面這種使用匿名函數的方式添加的事件是不能移除的,因爲兩個匿名函數雖然代碼一樣,但本質上他們是兩個不同的函數
-
xc.addEventListener('click',function(){
-
alert(this.innerHTML);
-
},false);
-
xc.removeEventListener('click',function(){
-
alert(this.innerHTML);
-
},false);
-
*/
- </script>
5.所添加的事件必須是事件對象支持的事件,比如給window對象添加click事件就不會成功,因爲window沒有click事件
6.解決IE6 IE7 IE8 attchEvent this指向window的方法:
要解決IE6 IE7 IE8 attachEvent this指向錯誤,有至少以下三種方法:
(1).使用事件處理函數.apply(事件對象,arguments),代碼如下
以下代碼僅適用於IE6 IE7 IE8,這種方式的缺點是綁定的事件無法取消綁定,原因上面已經說了,匿名函數和匿名函數之間是互不相等的。
-
<a id="xc">點擊</a>
-
<script type="text/javascript">
-
var object=document.getElementById('xc');
-
function handler(){
-
alert(this.innerHTML);
-
}
-
object.attachEvent('onclick',function(){
-
handler.call(object,arguments);
-
});
- </script>
(2)使用事件源代替this關鍵字
以下代碼僅適用於IE6 IE7 IE8,這種方式完全忽略this關鍵字,但寫起來稍顯麻煩。
-
<a id="xc">點擊</a>
-
<script type="text/javascript">
-
function handler(e){
-
e=e||window.event;
-
var _this=e.srcElement||e.target;
-
alert(_this.innerHTML);
-
}
-
var object=document.getElementById('xc');
-
object.attachEvent('onclick',handler);
- </script>
(3)自己寫一個函數完全代替attachEvent/detachEvent,並且支持所有主流瀏覽器、解決IE6
IE7 IE8事件綁定導致的先綁定後執行問題。
下面是完美兼容addEventListener/removeEventListener和attachEvent/detachEvent的函數,支持Google Chrome/Firefox/Safari/Opera/IE 6 7 8 9 10 11等所有主流瀏覽器,能夠完美解決IE6 IE7 IE8 this指向錯誤,能夠糾正IE6 IE7 IE8中事件先綁定後執行的錯誤。
爲了避免代碼被編輯器修改,請下載附件測試。不要直接複製下面的代碼。
注意,本函數是全局函數,而不是DOM對象的成員方法。
<a id="xc">點擊</a>
<script type="text/javascript">
/*
* 添加事件處理程序
* @param object object 要添加事件處理程序的元素
* @param string type 事件名稱,如click
* @param function handler 事件處理程序,可以直接以匿名函數的形式給定,或者給一個已經定義的函數名。匿名函數方式給定的事件處理程序在IE6 IE7 IE8中可以移除,在標準瀏覽器中無法移除。
* @param boolean remove 是否是移除的事件,本參數是爲簡化下面的removeEvent函數而寫的,對添加事件處理程序不起任何作用
*/
function addEvent(object,type,handler,remove){
if(typeof object!='object'||typeof handler!='function') return;
try{
object[remove?'removeEventListener':'addEventListener'](type,handler,false);
}catch(e){
var xc='_'+type;
object[xc]=object[xc]||[];
if(remove){
var l=object[xc].length;
for(var i=0;i<l;i++){
if(object[xc][i].toString()===handler.toString()) object[xc].splice(i,1);
}
}else{
var l=object[xc].length;
var exists=false;
for(var i=0;i<l;i++){
if(object[xc][i].toString()===handler.toString()) exists=true;
}
if(!exists) object[xc].push(handler);
}
object['on'+type]=function(){
var l=object[xc].length;
for(var i=0;i<l;i++){
object[xc][i].apply(object,arguments);
}
}
}
}
/*
* 移除事件處理程序
*/
function removeEvent(object,type,handler){
addEvent(object,type,handler,true);
}
</script>
<script type="text/javascript">
function handler(){
alert(this.innerHTML);
}
var object=document.getElementById('xc');
addEvent(object,'click',handler);
//如果要測試綁定事件,請先刪除下面這一行。
removeEvent(object,'click',handler);
</script>