最近在看《javascript 高級(jí)程序》一書(shū),寫(xiě)自己的一些小心得體會(huì),希望得到牛人們的指點(diǎn),討論。
步入今天的正題,javascript事件處理函數(shù),我們知道,javascript與HTML之間的交互是通過(guò)事件來(lái)實(shí)現(xiàn)的,事件就是用戶(hù)或?yàn)g覽器自身執(zhí)行的某種動(dòng)作,比如click、mounseover、load……,而響應(yīng)事件的函數(shù)就叫做事件處理函數(shù)(或事件偵聽(tīng)器)。
1 |
<input type="button" value="click me" onclick="alert('click me')" /> |
這里我們把事件處理程序直接內(nèi)聯(lián)到了HTML代碼中,但這對(duì)于我們閱讀代碼極不友好,下面我們把事件處理程序分離出去,如下:
1 |
function showMessage() { |
然后我們?cè)贖TML代碼中去調(diào)用:
1 |
<input type="button" value="click me" onclick="showMessage()" /> |
在HTML中指定事件處理函數(shù)有兩個(gè)缺點(diǎn):
1. 存在時(shí)差的問(wèn)題,以上面的例子來(lái)說(shuō),假設(shè)showMessage()函數(shù)定義在頁(yè)面的最底部,如果用戶(hù)在解析showMessage()函數(shù)之前就單擊了按鈕,這樣就會(huì)引發(fā)錯(cuò)誤。為此,很多HTML事件處理函數(shù)都會(huì)封閉在 try -catch 塊中,這樣錯(cuò)誤就不會(huì)暴露出來(lái)了,如下:
1 |
<input type="button" value="click me" onclick="try {showMessage()} catch(e) {}" /> |
2. HTML代碼與javascript代碼緊密耦合,如果要更新事件處理函數(shù),就需要更新更新兩處位置。由于存在這兩個(gè)問(wèn)題,我們?cè)趯?shí)際的工作中一般比較少用這種事件處理方式。
1 |
var btn = document.getElementById("myBtn"); |
2 |
btn.onclick = function() { |
將一個(gè)函數(shù)賦值給一個(gè)事件處理程序的屬性,由于該方法至今的所有現(xiàn)在瀏覽器都支持,具有使用簡(jiǎn)單,跨瀏覽器的優(yōu)勢(shì)!使用DOM0級(jí)方法指定的事件處理程序被認(rèn)為是元素的方法,這個(gè)時(shí)候事件都是在元素的作用域中運(yùn)行的,也就是說(shuō)程序中的this引用當(dāng)前的元素。
也可以刪除通過(guò)DOM0級(jí)方法指定的事件處理程序,如下:
DOM2級(jí)事件定義了兩個(gè)方法:addEventListener()、removeEventListener()
要在按鈕上為click添加事件處理程序,可以使用如下代碼:
1 |
var btn = document.getElementById("myBtn"); |
2 |
btn.addEventListener("click", function() { |
因?yàn)榈谌齻€(gè)參數(shù)為false,所以事件會(huì)在冒泡階段觸發(fā)。使用DOM2級(jí)事處理程序的好處是可以添加多個(gè)事件處理程序。
同樣我們可以通過(guò)removeEventListener()來(lái)移除事件處理程序,如下:
1 |
var btn = document.getElementById("myBtn"); |
2 |
btn.removeEventListener("click", function() { |
IE中實(shí)現(xiàn)了與DOM類(lèi)似的兩個(gè)方法,attachEvent, deatachEvent(),如下代碼所示:
1 |
var btn = document.getElementById("myBtn"); |
2 |
btn.attachEvent("click", function() { |
6 |
var btn = document.getElementById("myBtn"); |
7 |
btn.detachEvent("click", function() { |
由于DOM2級(jí)事件處理程序與IE中的事件處理程序不同,我們可能利用能力檢測(cè)統(tǒng)一事件處理程序,如下代碼所示:
02 |
addListener: function(element, type, hander) { |
03 |
if (element.addEventListener) { |
04 |
element.addEventListener(type, hander, false); |
05 |
} else if (element.attachEvent) { |
06 |
element.attachEvent('on' + type, hander); |
08 |
element['on' + type] = hander; |
12 |
removeListener: function(element, type, hander) { |
13 |
if (element.removeEventListener) { |
14 |
element.removeEventListener(type, hander, false); |
15 |
} else if (element.deattachEvent) { |
16 |
element.detachEvent(type, hander); |
18 |
element['on' + type] = null; |
兼容DOM的瀏覽器會(huì)有一個(gè)event對(duì)象傳入到事件處理程序中,無(wú)論指定的事件處理程序時(shí)使用何方法,都會(huì)傳入event對(duì)象,我們常用的event對(duì)象的屬性及方法有:
1. currentTarget: 其事件處理程序當(dāng)前正在處理事件的那個(gè)元素;
2. target: 事件的目標(biāo);
3. preventDefault(): 取消事件的默認(rèn)行為;
4. stopPropagation(): 取消事件進(jìn)一步捕獲劃冒泡。
與DOM中的事件對(duì)象一樣,IE中的事件對(duì)象同樣有以上屬性或方法,但是實(shí)現(xiàn)起來(lái)有些不一樣,以下是他們間的對(duì)應(yīng)關(guān)系:
1. srcElement <=> target;
2. returnValue = false <=> preventDefault();
3. cancelBubble = true <=> stopPropagation();
由于DOM中的事件對(duì)象與IE中存在差異,我們同樣可以利用能力檢測(cè)的方法來(lái)統(tǒng)一事件對(duì)象中常用的屬性和方法(eventUtil.js):
02 |
addListener: function(element, type, hander) { |
03 |
if (element.addEventListener) { |
04 |
element.addEventListener(type, hander, false); |
05 |
} else if (element.attachEvent) { |
06 |
element.attachEvent('on' + type, hander); |
08 |
element['on' + type] = hander; |
12 |
getEvent: function(event) { |
13 |
return event || window.event; |
14 |
//return event ? event : window.event; |
17 |
getTarget: function(event) { |
18 |
return event.target || event.srcElement; |
21 |
preventDefault: function(event) { |
22 |
if (event.preventDefault) { |
23 |
event.preventDefault(); |
25 |
event.returnValue = false; |
29 |
removeListener: function(element, type, hander) { |
30 |
if (element.removeEventListener) { |
31 |
element.removeEventListener(type, hander, false); |
32 |
} else if (element.deattachEvent) { |
33 |
element.detachEvent(type, hander); |
35 |
element['on' + type] = null; |
39 |
stopPropagation: function(event) { |
40 |
if (event.stopPropagation) { |
41 |
event.stopPropagation(); |
43 |
event.cancelBubble = true; |
最后我們能過(guò)一個(gè)簡(jiǎn)單的示例來(lái)演示如何使用自定義的eventUtil對(duì)象,完整示例代碼如下:
03 |
<title>event util test</title> |
04 |
<script type="text/javascript" src="eventUtil.js"></script> |
07 |
<a href="//www.baidu.com">baidu</a> |
08 |
<script type="text/javascript"> |
10 |
var btn = document.getElementById("btn"); |
11 |
var link = document.getElementsByTagName("a")[0]; |
12 |
eventUtil.addListener(link, "click", function(event) { |
13 |
alert("prevent default event"); |
14 |
var event = eventUtil.getEvent(event); |
15 |
eventUtil.preventDefault(event); |
18 |
eventUtil.addListener(btn, "click", function(event) { |
19 |
var event = eventUtil.getEvent(event); |
20 |
var target = eventUtil.getTarget(event); |
23 |
eventUtil.stopPropagation(event); |
26 |
eventUtil.addListener(document.body, "click", function() { |
標(biāo)簽:
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:博客園