JavaScript中為事件指定處理程序的五種方式分析
本文實(shí)例講述了JavaScript中為事件指定處理程序的五種方式。分享給大家供大家參考,具體如下:
JavaScript和HTML之間的交互是通過事件實(shí)現(xiàn)的。
IE9、Firefox、Opera、Sarifi、Chrome都已經(jīng)實(shí)現(xiàn)了DOM2級(jí)事件模塊的核心部分,IE8是最后一個(gè)仍然使用其專有事件系統(tǒng)的主要瀏覽器。
事件流:
事件流描述的是從頁面中接受事件的順序,但I(xiàn)E和Netscape卻提出了完全相反的事件流的概念,IE的事件流是事件冒泡流,而Netscape的事件流是事件捕獲流。
1) 事件冒泡
事件開始時(shí)由最具體的元素(文檔中嵌套層次最深的那個(gè)節(jié)點(diǎn)接收,然后逐級(jí)向上傳播到較為不具體的節(jié)點(diǎn)(文檔)。
不支持事件冒泡的事件:blur、focus、load、unload。
2) 事件捕獲
不太具體的節(jié)點(diǎn)應(yīng)該更早接收到事件,而最具體的節(jié)點(diǎn)應(yīng)該最后接收到事件。事件捕獲的用意在于事件到達(dá)預(yù)定目標(biāo)之前捕獲它。
雖然IE9、Safari、Chrome、Firefox、Opera都支持事件捕獲和事件冒泡,但I(xiàn)E8及其更早版本只支持事件冒泡,不支持事件捕獲,因此。建議使用事件冒泡,在有特殊需要的時(shí)候再使用事件捕獲。
DOM事件流:
DOM2級(jí)事件規(guī)定的事件流包括三個(gè)階段:事件捕獲階段,處于目標(biāo)階段和事件冒泡階段。實(shí)際上,在事件捕獲階段預(yù)定目標(biāo)不會(huì)接收到事件,處于目標(biāo)階段事件在預(yù)定目標(biāo)上發(fā)生。事件處理中,處于目標(biāo)階段被看成事件冒泡階段的一部分。但是,即使“DOM2級(jí)事件”規(guī)范明確要求捕獲階段不會(huì)涉及事件目標(biāo),但I(xiàn)E9、 Safari、Chrome、Firefox和Opera9.5及更高版本都會(huì)在捕獲階段觸發(fā)事件對(duì)象上的事件,結(jié)果是有兩個(gè)機(jī)會(huì)在目標(biāo)對(duì)象上操作事 件。
IE9、Firefox、Opera、Sarifi、Chrome都支持DOM事件流,IE8及其更早版本不支持DOM事件流。
事件處理程序:
事件就是用戶或?yàn)g覽器自身執(zhí)行的某種動(dòng)作,而響應(yīng)某個(gè)事件的函數(shù)就是事件處理程序(或事件偵聽器),事件處理程序的名字以“on”開頭。
JavaScript中有五種事件處理程序方式:
1) HTML事件處理程序
每種事件都可以使用一個(gè)與相應(yīng)事件處理程序同名的HTML特性來指定,特性的值可以是能夠執(zhí)行的JavaScript代碼,也可以是函數(shù)。函數(shù)中有一個(gè)局部變量event,通過event變量可以訪問事件對(duì)象;在函數(shù)內(nèi)部,this值等于事件的目標(biāo)元素。
在HTML中指定事件處理程序的幾個(gè)缺點(diǎn):
① 時(shí)差問題:用戶可能在HTML元素一出現(xiàn)在頁面上就觸發(fā)相應(yīng)的事件,但當(dāng)時(shí)的事件處理程序有可能尚不具備執(zhí)行條件,如用戶在解析事件處理函數(shù)之前就觸發(fā)事件。為此,很多HTML事件處理程序都會(huì)封裝在一個(gè)try-catch塊中,以便及時(shí)捕獲錯(cuò)誤,以免錯(cuò)誤拋出被用戶看到。
② 擴(kuò)展事件處理程序的作用域鏈在不同瀏覽器中會(huì)導(dǎo)致不同的結(jié)果。不同JavaScript引擎遵循的標(biāo)識(shí)符解析規(guī)則略有差異,很有可能會(huì)在訪問非限定對(duì)象成員時(shí)出錯(cuò)。
③ HTML代碼與JavaScript代碼緊密耦合,更換事件處理程序需要改動(dòng)HTML代碼與JavaScript代碼。
2) DOM0級(jí)事件處理程序
通過JavaScript指定事件處理程序的傳統(tǒng)方式,將一個(gè)函數(shù)賦值給一個(gè)事件處理程序?qū)傩?。使用DOM0級(jí)方法指定的事件處理程序被認(rèn)為是元素的方法,因此this引用當(dāng)前元素。
DOM0級(jí)事件處理程序的優(yōu)勢(shì):
① 簡單;
② 跨瀏覽器
可以通過將事件處理程序的值設(shè)置為null來刪除通過DOM0級(jí)方法指定的事件處理程序。
3) DOM2級(jí)事件處理程序
DOM2級(jí)事件定義了兩種方法,用于指定和刪除事件處理程序的操作:addEventListener()和removeEventListener(),它們都接收3個(gè)參數(shù):要處理的事件名、作為事件處理程序的函數(shù)和一個(gè)布爾值(true表示在捕獲階段調(diào)用事件處理程序,false表示在冒泡階段調(diào)用事件處理程序)。
DOM2級(jí)事件處理程序的優(yōu)勢(shì):
可以添加多個(gè)事件處理程序,它們會(huì)按照添加它們的順序觸發(fā)。
通過addEventListener()添加的事件處理程序只能用removeEventListener()來移除,但要求移除時(shí)傳入的參數(shù)與添加事件處理程序時(shí)使用的參數(shù)相同,因此通過addEventListener()添加的匿名函數(shù)將無法移除,需要給removeEventListener()傳入addEventListener()中命名的函數(shù)才能正常移除。
4) IE事件處理程序
IE事件定義了兩個(gè)方法:attachEvent()和detachEvent(),它們都接收2個(gè)參數(shù):要處理的事件名、作為事件處理程序的函數(shù).由于IE8及其更早版本只支持事件冒泡,所以通過attachEvent()添加的事件處理程序都會(huì)被添加到冒泡階段。
注意:通過IE的attachEvent()添加的事件處理程序的名字以“on”開頭,而通過DOM的addEventListener()添加的名字不是。
在IE中使用attachEvent()與使用DOM0級(jí)方法的主要區(qū)別:
事件處理程序的作用域不同。在IE中使用attachEvent(),事件處理程序會(huì)在全局作用域中運(yùn)行,因此this等于window;而使用DOM0級(jí)方法,事件處理程序會(huì)在其所屬元素的作用域中運(yùn)行。
在IE中使用attachEvent()與使用DOM2級(jí)方法的區(qū)別:
添加多個(gè)事件處理程序的執(zhí)行順序不同。在IE中使用attachEvent(),可以添加多個(gè)事件處理程序,它們會(huì)按照添加它們的相反順序觸發(fā);在DOM中使用addEventListener(),可以添加多個(gè)事件處理程序,但它們會(huì)按照添加它們的順序觸發(fā)。
通過attachEvent()添加的事件處理程序只能用detachEvent()來移除,但要求移除時(shí)傳入的參數(shù)與添加事件處理程序時(shí)使用的參數(shù)相同,因此通過attachEvent()添加的匿名函數(shù)將無法移除,需要給detachEvent()傳入attachEvent()中命名的函數(shù)才能正常移除。
5) 跨瀏覽器的事件處理程序
要保證事件處理程序的代碼在大多數(shù)瀏覽器下一致地運(yùn)行,只需關(guān)注冒泡階段。
視情況分別使用DOM2級(jí)方法、IE方法、DOM0級(jí)方法來添加和移除事件,addHandler()和removeHandler()方法屬于EventUtil對(duì)象。
① 先檢測(cè)傳入的元素是否存在DOM2級(jí)方法(傳入的第三個(gè)參數(shù)為false以表示冒泡階段);
② 再檢測(cè)傳入的元素是否存在IE的方法;
③ 最后檢測(cè)傳入的元素是否存在DOM0級(jí)方法(使用方括號(hào)語法將屬性名指定為事件處理程序)。
var EventUtil = {
addHandler:function(element, type, handler) {
if (element.addEventListener)
element.addEventListener(type, handler, false);
else if (element.attachEvent)
element.attachEvent("on" + type, handler);
else
element["on" + type] = handler;
},
removeHandler:function(element, type, handler) {
if (element.removeEventListener)
element.removeEventListener(type, handler, false);
else if (element.detachEvent)
element.detachEvent(“on” + type, handler);
else
element["on" + type] = null;
}
}
PS:關(guān)于javascript事件說明可參考本站javascript事件與功能說明大全:http://tools.jb51.net/table/javascript_event
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《JavaScript事件相關(guān)操作與技巧大全》、《JavaScript頁面元素操作技巧總結(jié)》、《JavaScript操作DOM技巧總結(jié)》、《JavaScript查找算法技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
相關(guān)文章
js 獲取和設(shè)置css3 屬性值的實(shí)現(xiàn)方法
本篇文章介紹了,使用js 獲取和設(shè)置css3 屬性值的實(shí)現(xiàn)方法。需要的朋友參考下2013-05-05
10個(gè)必備的JavaScript?async/await工具函數(shù)分享
當(dāng)談到異步編程時(shí),async/await是JavaScript中常用的功能之一,本文為大家整理了10個(gè)常用的await和async函數(shù)示例,感興趣的小伙伴可以參考一下2023-12-12
如何用js實(shí)現(xiàn)鼠標(biāo)向上滾動(dòng)時(shí)浮動(dòng)導(dǎo)航
今天給大家介紹一下使用JavaScript判斷鼠標(biāo)滑輪是不是向上滾動(dòng),當(dāng)向上滾動(dòng)的時(shí)候,導(dǎo)航條浮動(dòng)在頂部位置。示例代碼如下。2016-07-07
JavaScript中立即執(zhí)行函數(shù)實(shí)例詳解
javascript和其他編程語言相比比較隨意,所以javascript代碼中充滿各種奇葩的寫法,有時(shí)霧里看花,當(dāng)然,能理解各型各色的寫法也是對(duì)javascript語言特性更進(jìn)一步的深入理解。這篇文章主要給大家介紹了關(guān)于JavaScript中立即執(zhí)行函數(shù)的相關(guān)資料,需要的朋友可以參考下。2017-11-11
JS+CSS實(shí)現(xiàn)的日本門戶網(wǎng)站經(jīng)典選項(xiàng)卡導(dǎo)航效果
這篇文章主要介紹了JS+CSS實(shí)現(xiàn)的日本門戶網(wǎng)站經(jīng)典選項(xiàng)卡導(dǎo)航效果,涉及JavaScript針對(duì)頁面元素的動(dòng)態(tài)遍歷及樣式動(dòng)態(tài)修改技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09

