最近在看《javascript 高級程序》一書,寫自己的一些小心得體會,希望得到牛人們的指點,討論。
步入今天的正題,javascript事件處理函數,我們知道,javascript與HTML之間的交互是通過事件來實現的,事件就是用戶或瀏覽器自身執行的某種動作,比如click、mounseover、load……,而響應事件的函數就叫做事件處理函數(或事件偵聽器)。
1 |
<input type="button" value="click me" onclick="alert('click me')" /> |
這里我們把事件處理程序直接內聯到了HTML代碼中,但這對于我們閱讀代碼極不友好,下面我們把事件處理程序分離出去,如下:
1 |
function showMessage() { |
然后我們在HTML代碼中去調用:
1 |
<input type="button" value="click me" onclick="showMessage()" /> |
在HTML中指定事件處理函數有兩個缺點:
1. 存在時差的問題,以上面的例子來說,假設showMessage()函數定義在頁面的最底部,如果用戶在解析showMessage()函數之前就單擊了按鈕,這樣就會引發錯誤。為此,很多HTML事件處理函數都會封閉在 try -catch 塊中,這樣錯誤就不會暴露出來了,如下:
1 |
<input type="button" value="click me" onclick="try {showMessage()} catch(e) {}" /> |
2. HTML代碼與javascript代碼緊密耦合,如果要更新事件處理函數,就需要更新更新兩處位置。由于存在這兩個問題,我們在實際的工作中一般比較少用這種事件處理方式。
1 |
var btn = document.getElementById("myBtn"); |
2 |
btn.onclick = function() { |
將一個函數賦值給一個事件處理程序的屬性,由于該方法至今的所有現在瀏覽器都支持,具有使用簡單,跨瀏覽器的優勢!使用DOM0級方法指定的事件處理程序被認為是元素的方法,這個時候事件都是在元素的作用域中運行的,也就是說程序中的this引用當前的元素。
也可以刪除通過DOM0級方法指定的事件處理程序,如下:
DOM2級事件定義了兩個方法:addEventListener()、removeEventListener()
要在按鈕上為click添加事件處理程序,可以使用如下代碼:
1 |
var btn = document.getElementById("myBtn"); |
2 |
btn.addEventListener("click", function() { |
因為第三個參數為false,所以事件會在冒泡階段觸發。使用DOM2級事處理程序的好處是可以添加多個事件處理程序。
同樣我們可以通過removeEventListener()來移除事件處理程序,如下:
1 |
var btn = document.getElementById("myBtn"); |
2 |
btn.removeEventListener("click", function() { |
IE中實現了與DOM類似的兩個方法,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級事件處理程序與IE中的事件處理程序不同,我們可能利用能力檢測統一事件處理程序,如下代碼所示:
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的瀏覽器會有一個event對象傳入到事件處理程序中,無論指定的事件處理程序時使用何方法,都會傳入event對象,我們常用的event對象的屬性及方法有:
1. currentTarget: 其事件處理程序當前正在處理事件的那個元素;
2. target: 事件的目標;
3. preventDefault(): 取消事件的默認行為;
4. stopPropagation(): 取消事件進一步捕獲劃冒泡。
與DOM中的事件對象一樣,IE中的事件對象同樣有以上屬性或方法,但是實現起來有些不一樣,以下是他們間的對應關系:
1. srcElement <=> target;
2. returnValue = false <=> preventDefault();
3. cancelBubble = true <=> stopPropagation();
由于DOM中的事件對象與IE中存在差異,我們同樣可以利用能力檢測的方法來統一事件對象中常用的屬性和方法(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; |
最后我們能過一個簡單的示例來演示如何使用自定義的eventUtil對象,完整示例代碼如下:
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() { |
標簽:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客園