鍍金池/ 教程/ HTML/ 淺談 Javascript 事件處理程序的幾種方式
淺談 JavaScript 之事件綁定
淺談 javascript 中字符串 String 與數(shù)組 Array
淺談 javascript 中基本包裝類型
淺談 JavaScript Math 和 Number 對(duì)象
淺談 Javascript 的靜態(tài)屬性和原型屬性
淺談 JavaScript 中定義變量時(shí)有無 var 聲明的區(qū)別
淺談 JavaScript Array 對(duì)象
淺談 JavaScript 函數(shù)參數(shù)的可修改性問題
淺談 javascript 中的 instanceof 和 typeof
淺談 JavaScript 中 Date (日期對(duì)象),Math 對(duì)象
淺談 Javascript 執(zhí)行順序
淺談 javascript 函數(shù)屬性和方法
淺談 JavaScript 中面向?qū)ο蠹夹g(shù)的模擬
淺談 javascript 的原型繼承
淺談 javascript 事件取消和阻止冒泡
根據(jù)一段代碼淺談 Javascript 閉包
淺談 Javascript 面向?qū)ο缶幊?/span>
淺談 javascript 六種數(shù)據(jù)類型以及特殊注意點(diǎn)
淺談 Javascript 變量作用域問題
淺談 javascript 函數(shù)內(nèi)部屬性
淺談 javascript 中自定義模版
淺談 JavaScript 字符集
淺談 javascript 面向?qū)ο缶幊?/span>
淺談 JavaScript 框架分類
淺談 JavaScript 中的 Math.atan() 方法的使用
淺談 Javascript 數(shù)組與字典
淺談 JavaScript 數(shù)據(jù)類型及轉(zhuǎn)換
淺談 javascript 的調(diào)試
淺談 Javascript 嵌套函數(shù)及閉包
淺談 javascript 回調(diào)函數(shù)
淺談 JavaScript Date 日期和時(shí)間對(duì)象
淺談 Javascript 中的 Function 與 Object
淺談 JavaScript 數(shù)據(jù)類型
淺談 javascript 中 this 在事件中的應(yīng)用
淺談 javascript 中的閉包
淺談 javascript 函數(shù)劫持
淺談 Javascript 中深復(fù)制
淺談 JavaScript 函數(shù)節(jié)流
淺談 JavaScript 中的 String 對(duì)象常用方法
淺談 JavaScript 事件的屬性列表
淺談 JavaScript 函數(shù)與棧
淺談 JavaScript 的事件
淺談 javascript 中的作用域
淺談 JavaScript 的執(zhí)行效率
淺談 Javascript 事件模擬
淺談 JavaScript function 函數(shù)種類
淺談 javascript 歸并方法
淺談 javascript 迭代方法
淺談 JavaScript 編程語言的編碼規(guī)范
淺談 JavaScript 實(shí)現(xiàn)面向?qū)ο笾械念?/span>
淺談 Javascript 鼠標(biāo)和滾輪事件
淺談 Javascript Base64 加密解密
淺談 Javascript 中勻速運(yùn)動(dòng)的停止條件
淺談 javascript 實(shí)現(xiàn)八大排序
淺談 javascript 的分號(hào)的使用
淺談 javascript 中 createElement 事件
淺談 javascript 的數(shù)據(jù)類型檢測(cè)
淺談 javascript 對(duì)象模型和 function 對(duì)象
淺談 Javascript 如何實(shí)現(xiàn)勻速運(yùn)動(dòng)
淺談 JavaScript 字符串與數(shù)組
淺談 javascript 面向?qū)ο蟪绦蛟O(shè)計(jì)
淺談 Javascript 事件處理程序的幾種方式

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

事件就是用戶或?yàn)g覽器自身執(zhí)行的某種動(dòng)作。比如說 click,mouseover,都是事件的名字。而相應(yīng)某個(gè)事件的函數(shù)就叫事件處理程序(或事件偵聽器)。為事件指定處理程序的方式有好幾種。

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(){ <br>alert("hello world!"); <br>},false); <br>  

這里為按鈕添加了兩個(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);// 移除 <br>btn.removeEventListener("click",function(){// 這樣寫沒有用 (因?yàn)槲傅诙闻c第一次相比是一個(gè)完全不同的函數(shù)) <br>alert(this.id); <br>},false); <br>  

解決辦法:

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 來添加和移除事件處理程序還是很方便的。