jQuery事件與事件對象
首先看一下我們經(jīng)常使用的添加事件的方式:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>javascript中的事件</title> <script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script> <script type="text/javascript"> $(function() { document.getElementById("testDiv2").onclick = showMsg; }) function showMsg(event) { alert("!!!"); } </script></head><body> <div id="testDiv1" onclick="showMsg();">單擊事件 1</div> <div id="testDiv2">單擊事件 2</div> </body> </html>
我們最常使用為元素添加onclick元素屬性的方式添加事件.
為testDiv2的添加onclick事件的方式是修改Dom屬性.
在上一章中已經(jīng)說明了什么是元素屬性, 什么是Dom屬性.這兩種方式的效果相同. 當單擊div時會顯示提示框.
請注意, 雖然效果相同, 但是并不等效.
document.getElementById("testDiv2").onclick = showMsg;
等效于:
<div id="testDiv1" onclick="alert("!!!");">單擊事件 1</div>
注意兩者的區(qū)別了嗎? 我們常用的修改元素屬性添加事件的方式, 實際上是建立了一個匿名函數(shù):
document.getElementById("testDiv1").onclick = function(event) { alert("!!!"); };
這個匿名函數(shù)的簽名和我們手寫的showMsg簽名相同, 所以可以把showMsg直接賦值給onclick.
這種方式的弊端是:
1. 只能為一個事件綁定一個事件處理函數(shù). 使用"="賦值會把前面為此時間綁定的所有事件處理函數(shù)沖掉.
2. 在事件函數(shù)(無論是匿名函數(shù)還是綁定的函數(shù))中獲取事件對象的方式在不同瀏覽器中要特殊處理:
IE中,事件對象是window對象的一個屬性.事件處理函數(shù)必須這樣訪問事件對象:
obj.onclick=function() { var oEvent = window.event; }
在DOM標準中,事件對象必須作為唯一參數(shù)傳給事件處理函數(shù):
obj.onclick=function() { var oEvent = arguments[0]; }
除了使用argument[0]訪問此參數(shù), 我們也可以指定參數(shù)名稱,上面的代碼等同于:
obj.onclick=function(oEvent) { }
目前兼容DOM的瀏覽器有Firefox,Safari,Opera,IE7等.
3. 添加多播委托的函數(shù)在不同瀏覽器中是不一樣的.
下面是在"Javascript公共腳本庫系列(二): 添加事件多播委托的方法"文章中, 提供的兼容多瀏覽器添加多播委托的方法:
//統(tǒng)一的為對象添加多播事件委托的方法 /* 參數(shù)說明: oTarget : 要添加事件的對象.比如"document". sEventType : 事件類型.比如單擊事件"click". fnHandler : 發(fā)生事件時調(diào)用的方法. 比如一個靜態(tài)函數(shù)"hideCalendar"
使用舉例:
//單擊頁面的任何元素,只要沒有取消冒泡,都可以關(guān)閉日歷控件 var cf = document.getElementById("CalFrame"); if( cf != null && hideCalendar != null ) { ScriptHelper.addEventListener( document, "click", hideCalendar ); } */ scriptHelper.prototype.addEventListener = function(oTarget, sEventType, fnHandler) { if( oTarget.addEventListener )//for dom { oTarget.addEventListener( sEventType, fnHandler, false ) } else if( oTarget.attachEvent )//for ie { oTarget.attachEvent( "on" + sEventType, fnHandler); } }
所以我們首先應(yīng)該摒棄<div onclick="..."></div>這種通過修改元素屬性添加事件的方式. 盡量使用添加多播事件委托的方式為一個事件綁定多個事件處理函數(shù), 比如為document對象的單擊事件添加一個關(guān)閉彈出層的方法, 使用多播就不會影響document對象原有的事件處理函數(shù).