淺談Javascript事件處理程序的幾種方式
一:HTML事件處理程序。
如:
<script type="text/javascript">
function show(){
alert('hello world!');
}
</script>
<input type="button" value="click me" onclick="show()"/>
相信這種方式是目前咱們大家用得比較多的一種,但是在html中指定事件處理程序有兩個(gè)缺點(diǎn)。
(1)首先:存在一個(gè)時(shí)差問題。就本例子來說,假設(shè)show()函數(shù)是在按鈕下方,頁面的最底部定義的,如果用戶在頁面解析show()函數(shù)之前就單擊了按鈕,就會(huì)引發(fā)錯(cuò)誤;
(2)第二個(gè)缺點(diǎn)是html與javascript代碼緊密耦合。如果要更換時(shí)間處理程序,就要改動(dòng)兩個(gè)地方:html代碼和javascript代碼。
因此,許多開發(fā)人員摒棄html事件處理程序,轉(zhuǎn)而使用javascript指定事件處理程序。
二:Javascript指定事件處理程序
javascript指定事件處理程序包括三種方式:
(1):DOM0級(jí)事件處理程序
如:
var btn=document.getElementById("mybtn"); //取得該按鈕的引用
btn.onclick=function(){
alert('clicked');
alert(this.id); // mybtn
以這種方式添加的事件處理程序會(huì)在事件流的冒泡階段被處理。
刪除DOM0級(jí)方法指定的事件處理程序:
btn.onclick=null; // 刪除事件處理程序
}
(2):DOM2級(jí)事件處理程序
DOM2級(jí)事件定義了兩個(gè)方法,用于處理指定和刪除事件處理程序的操作:addEventListener()和removeEventListener()。所有DOM節(jié)點(diǎn)中都包含這兩個(gè)方法,并且它們都接受3個(gè)參數(shù):要處理的事件名,做為事件處理程序的函數(shù)和一個(gè)布爾值。最后這個(gè)參數(shù)如果是true,表示在捕獲階段調(diào)用事件處理程序;如果是fasle,表示在冒泡階段調(diào)用事件處理程序。
如:
var btn=document.getElementById("mybtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
使用DOM2級(jí)事件處理程序的主要好處是可以添加多個(gè)事件處理程序。
如:
var btn=document.getElementById("mybtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
btn.addEventListener("click",function(){
alert("hello world!");
},false);
這里為按鈕添加了兩個(gè)事件處理程序。這兩個(gè)事件處理程序會(huì)按照它們的順序觸發(fā)。
通過addEventListener()添加的時(shí)間處理程序只能使用removeEventListener()來移除,移除時(shí)傳入的參數(shù)與添加時(shí)使用的參數(shù)相同。這也意味著通過addEventListener()添加的匿名函數(shù)將無法移除。
如:
var btn=document.getElementById("mybtn");
btn.addEventListener("click",function(){
alert(this.id);
},false);
//移除
btn.removeEventListener("click",function(){ //這樣寫沒有用 (因?yàn)槲傅诙闻c第一次相比是一個(gè)完全不同的函數(shù))
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); // 有效
注意:這里我們的第三個(gè)參數(shù)都是false,是在冒泡階段添加的。大多數(shù)情況下,都是就事件處理程序添加到事件流的冒泡階段,這樣可以最大限度的兼容各種瀏覽器。
三:IE事件處理程序
IE實(shí)現(xiàn)了與DOM中類似的兩個(gè)方法:attachEvent()和detachEvent()。這兩個(gè)方法接受相同的兩個(gè)參數(shù):事件處理程序名稱和事件處理程序函數(shù)。由于IE只支持時(shí)間冒泡,所有通過attachEvent()添加的事件處理程序都會(huì)被添加包冒泡階段。
如:
三:
var btn=document.getElementById("mybtn");
btn.attachEvent("onclick",function(){
alert("clicked");
})
注意:attachEvent()函數(shù)的第一個(gè)參數(shù)是"onclick",而非DOM的addEventListener()中的"click"。
attachEvent()方法也可以用來為一個(gè)元素添加多個(gè)事件處理程序。
如:
var btn=document.getElementById("mybtn");
btn.attachEvent("onclick",function(){
alert("clicked");
});
btn.attachEvent("onclick",function(){
alert("hello world!");
});
這里調(diào)用了兩次attachEvent(),為同一個(gè)按鈕添加了兩個(gè)不同的事件處理程序。不過,與DOM方法不同的是,這些事件處理程序不是以它們的添加順序執(zhí)行,而是以相反的順序被觸發(fā)。單擊這個(gè)例子中的按鈕:首先看到的是"hello world",然后才是"clicked".
使用attachEvent()添加的事件可以通過detachEvent()來移除,條件是必須提供相同的參數(shù)。
var btn=document.getElementById("mybtn");
var hander=function(){
alert("clicked");
}
btn.detachEvent("onclick",hander}); // 移除
以上三種方式為目前的主要的事件處理程序方式,那看到這里你肯定會(huì)想到,既然不同的瀏覽器會(huì)有不同的差異,那怎么保證跨瀏覽器的事件處理程序呢?
為了以跨瀏覽器的方式處理事件,不少的開發(fā)人員是使用能夠隔離瀏覽器差異性的Javascript庫,還有一些開發(fā)人員會(huì)自己開發(fā)最合適的事件處理方法。
這里提供一個(gè)EventUtil對(duì)象,可以用這個(gè)對(duì)象來處理瀏覽期間的差異:
var EventUtil = {
addHandler: function(element, type, handler){ // 該方法接受3個(gè)參數(shù):要操作的元素,事件名稱和事件處理程序函數(shù)
if (element.addEventListener){ //檢查傳入的元素是否存在DOM2級(jí)方法
element.addEventListener(type, handler, false); // 若存在,則使用該方法
} else if (element.addEvent){ // 如果存在的是IE的方法
element.attachEvent("on" + type, handler); //則使用IE的方法,注意,這里的事件類型必須加上"on"前綴。
} else { // 最后一種可能是使用DOM0級(jí)
element["on" + type] = hander;
}
},
removeHandler: function(element, type, handler){ // 該方法是刪除之前添加的事件處理程序
if (element.removeEventListener){ //檢查傳入的元素是否存在DOM2級(jí)方法
element.removeEventListener(type, handler, false); // 若存在,則使用該方法
} else if (element.detachEvent){ // 如果存在的是IE的方法
element.detachEvent("on" + type, handler); //則使用IE的方法,注意,這里的事件類型必須加上"on"前綴。
} else { // 最后一種可能是使用DOM0及方法(在現(xiàn)代瀏覽器中,應(yīng)該不會(huì)執(zhí)行這里的代碼)
element["on" + type] = null;
}
}
};
可以像下面這樣使用EventUtil對(duì)象:
var btn =document.getElementById("mybtn");
var hander= function(){
alert("clicked");
};
//這里省略了部分代碼
EventUtil.addHandler(btn,"click",hander);
//這里省略了部分代碼
EventUtil.removeHandler(btn,"click",hander); //移除之前添加的事件處理程序
可見,使用addHandler和removeHandler來添加和移除事件處理程序還是很方便的。
相關(guān)文章
js實(shí)現(xiàn)消滅星星(web簡(jiǎn)易版)
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)web簡(jiǎn)易版的消滅星星,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03JsRender for index循環(huán)索引用法詳解
這篇文章主要介紹了JsRender for index循環(huán)索引用法,以實(shí)例形式詳細(xì)分析了JsRender中循環(huán)的用法,需要的朋友可以參考下2014-10-10javascript實(shí)現(xiàn)貪吃蛇小游戲思路
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)貪吃蛇思路小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09javascript 無限聯(lián)動(dòng)菜單效果代碼
javascript 無限聯(lián)動(dòng)菜單效果代碼,需要的朋友可以參考下。2010-04-04原生javascript實(shí)現(xiàn)圖片放大鏡效果
這篇文章主要為大家詳細(xì)介紹了原生javascript實(shí)現(xiàn)圖片放大鏡效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01javascript如何使用函數(shù)random來實(shí)現(xiàn)課堂隨機(jī)點(diǎn)名方法詳解
這篇文章主要介紹了javascript如何使用函數(shù)random來實(shí)現(xiàn)課堂隨機(jī)點(diǎn)名方法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07js控制不同的時(shí)間段顯示不同的css樣式的實(shí)例代碼
這篇文章介紹了js控制不同的時(shí)間段顯示不同的css樣式的實(shí)例代碼,有需要的朋友可以參考一下2013-11-11關(guān)于layui 實(shí)現(xiàn)點(diǎn)擊按鈕添加一行(方法渲染創(chuàng)建的table)
今天小編就為大家分享一篇關(guān)于layui 實(shí)現(xiàn)點(diǎn)擊按鈕添加一行(方法渲染創(chuàng)建的table),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09js使用for循環(huán)與innerHTML獲取選中tr下td值
這篇文章主要與大家分享了js使用for循環(huán)與innerHTML獲取選中tr下td值的方法,很簡(jiǎn)單,但很實(shí)用,有需要的朋友可以參考下2014-09-09