淺談Javascript事件處理常式的幾種方式

來源:互聯網
上載者:User

事件就是使用者或瀏覽器自身執行的某種動作。比如說click,mouseover,都是事件的名字。而相應某個事件的函數就叫事件處理常式(或事件接聽程式)。為事件指定處理常式的方式有好幾種。
一:HTML事件處理常式。
如: 複製代碼 代碼如下:<script type="text/javascript">
function show(){
alert('hello world!');
}
</script>
<input type="button" value="click me" onclick="show()"/>

相信這種方式是目前咱們大家用得比較多的一種,但是在html中指定事件處理常式有兩個缺點。
(1)首先:存在一個時差問題。就本例子來說,假設show()函數是在按鈕下方,頁面的最底部定義的,如果使用者在頁面解析show()函數之前就單擊了按鈕,就會引發錯誤;
(2)第二個缺點是html與javascript代碼緊密耦合。如果要更換時間處理常式,就要改動兩個地方:html代碼和javascript代碼。
因此,許多開發人員摒棄html事件處理常式,轉而使用javascript指定事件處理常式。
二:Javascript指定事件處理常式
javascript指定事件處理常式包括三種方式:
(1):DOM0級事件處理常式
如: 複製代碼 代碼如下:var btn=document.getElementById("mybtn"); //取得該按鈕的引用
btn.onclick=function(){
alert('clicked');
alert(this.id); // mybtn

以這種方式添加的事件處理常式會在事件流的冒泡階段被處理。
刪除DOM0級方法指定的事件處理常式:
btn.onclick=null; // 刪除事件處理常式
}
(2):DOM2級事件處理常式
DOM2級事件定義了兩個方法,用於處理指定和刪除事件處理常式的操作:addEventListener()和removeEventListener()。所有DOM節點中都包含這兩個方法,並且它們都接受3個參數:要處理的事件名,做為事件處理常式的函數和一個布爾值。最後這個參數如果是true,表示在捕獲階段呼叫事件處理常式;如果是fasle,表示在冒泡階段呼叫事件處理常式。
如: 複製代碼 代碼如下:var btn=document.getElementById("mybtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);

使用DOM2級事件處理常式的主要好處是可以添加多個事件處理常式。
如: 複製代碼 代碼如下:var btn=document.getElementById("mybtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
btn.addEventListener("click",function(){
alert("hello world!");
},false);

這裡為按鈕添加了兩個事件處理常式。這兩個事件處理常式會按照它們的順序觸發。
通過addEventListener()添加的時間處理常式只能使用removeEventListener()來移除,移除時傳入的參數與添加時使用的參數相同。這也意味著通過addEventListener()添加的匿名函數將無法移除。
如: 複製代碼 代碼如下:var btn=document.getElementById("mybtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
//移除
btn.removeEventListener("click",function(){ //這樣寫沒有用 (因為胃第二次與第一次相比是一個完全不同的函數)
alert(this.id);
},false);

解決辦法: 複製代碼 代碼如下:var btn=document.getElementById("mybtn");
var hander=function(){
alert(this.id);
};
btn.addEventListener("click",hander,false);

btn.removeEventListener("click",hander,false); // 有效

注意:這裡我們的第三個參數都是false,是在冒泡階段添加的。大多數情況下,都是就事件處理常式添加到事件流的冒泡階段,這樣可以最大限度的相容各種瀏覽器。
三:IE事件處理常式
IE實現了與DOM中類似的兩個方法:attachEvent()和detachEvent()。這兩個方法接受相同的兩個參數:事件處理常式名稱和事件處理常式函數。由於IE只支援時間冒泡,所有通過attachEvent()添加的事件處理常式都會被添加包冒泡階段。
如:

三: 複製代碼 代碼如下:var btn=document.getElementById("mybtn");
btn.attachEvent("onclick",function(){
alert("clicked");
})

注意:attachEvent()函數的第一個參數是"onclick",而非DOM的addEventListener()中的"click"。
attachEvent()方法也可以用來為一個元素添加多個事件處理常式。
如: 複製代碼 代碼如下:var btn=document.getElementById("mybtn");
btn.attachEvent("onclick",function(){
alert("clicked");
});
btn.attachEvent("onclick",function(){
alert("hello world!");
});

這裡調用了兩次attachEvent(),為同一個按鈕添加了兩個不同的事件處理常式。不過,與DOM方法不同的是,這些事件處理常式不是以它們的添加順序執行,而是以相反的順序被觸發。單擊這個例子中的按鈕:首先看到的是"hello world",然後才是"clicked".
使用attachEvent()添加的事件可以通過detachEvent()來移除,條件是必須提供相同的參數。 複製代碼 代碼如下:var btn=document.getElementById("mybtn");
var hander=function(){
alert("clicked");
}
btn.detachEvent("onclick",hander}); // 移除

以上三種方式為目前的主要的事件處理常式方式,那看到這裡你肯定會想到,既然不同的瀏覽器會有不同的差異,那怎麼保證跨瀏覽器的事件處理常式呢?
為了以跨瀏覽器的方式處理事件,不少的開發人員是使用能夠隔離瀏覽器差異性的Javascript庫,還有一些開發人員會自己開發最合適的事件處理方法。
這裡提供一個EventUtil對象,可以用這個對象來處理瀏覽期間的差異: 複製代碼 代碼如下:var EventUtil = {
addHandler: function(element, type, handler){ // 該方法接受3個參數:要操作的元素,事件名稱和事件處理常式函數
if (element.addEventListener){ //檢查傳入的元素是否存在DOM2級方法
element.addEventListener(type, handler, false); // 若存在,則使用該方法
} else if (element.addEvent){ // 如果存在的是IE的方法
element.attachEvent("on" + type, handler); //則使用IE的方法,注意,這裡的事件類型必須加上"on"首碼。
} else { // 最後一種可能是使用DOM0級
element["on" + type] = hander;
}
},

removeHandler: function(element, type, handler){ // 該方法是刪除之前添加的事件處理常式
if (element.removeEventListener){ //檢查傳入的元素是否存在DOM2級方法
element.removeEventListener(type, handler, false); // 若存在,則使用該方法
} else if (element.detachEvent){ // 如果存在的是IE的方法
element.detachEvent("on" + type, handler); //則使用IE的方法,注意,這裡的事件類型必須加上"on"首碼。
} else { // 最後一種可能是使用DOM0及方法(在現代瀏覽器中,應該不會執行這裡的代碼)
element["on" + type] = null;
}
}
};

可以像下面這樣使用EventUtil對象: 複製代碼 代碼如下:var btn =document.getElementById("mybtn");
var hander= function(){
alert("clicked");
};
//這裡省略了部分代碼
EventUtil.addHandler(btn,"click",hander);
//這裡省略了部分代碼
EventUtil.removeHandler(btn,"click",hander); //移除之前添加的事件處理常式

可見,使用addHandler和removeHandler來添加和移除事件處理常式還是很方便的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.