事件是什么臭挽,可以用來做什么捂襟,什么時候用到它?
事件欢峰,就是文檔或瀏覽器窗口中發(fā)生的一些特定的交互瞬間葬荷。JavaScript與HTML之間的交互是通過事件實現(xiàn)的
事件流
事件流描述的是從頁面中接收事件的順序
事件冒泡(event bubbling)
事件開始時由最具體的元素(文檔中嵌套層次最深的那個節(jié)點)接收,然后逐級向上傳播到較為不具體的節(jié)點(文檔)
事件捕獲(event capturing)
document對象首先接收到事件纽帖,然后事件沿DOM樹依次向下宠漩,一直傳播到事件的實際目標
DOM事件流
“DOM2級事件”規(guī)定的事件流包括三個階段:事件捕獲階段、處于目標階段和事件冒泡階段
在DOM事件流中懊直,實際的目標在捕獲階段不會接收到事件扒吁,目標的事件處理被看成冒泡階段的一部分。但IE9室囊、Safari雕崩、Chrome、FireFox和Opera9.5及更高版本都會在捕獲階段觸發(fā)事件對象上的事件融撞。結(jié)果盼铁,就是有兩個機會在目標對象上面操作事件。
事件處理程序
響應(yīng)某個事件的函數(shù)叫做事件處理程序(或事件偵聽器)
HTML事件處理程序
某個元素支持的每種事件尝偎,都可以使用一個與相應(yīng)事件處理程序同名的HTML特性來指定饶火。這個特性的值應(yīng)該是能夠執(zhí)行JavaScript代碼
<input type="button" value="Click Me" onclick="alert(this.value)">
或
<script type="text/javascript">
function showMessage() {
alert("Hello world!");
}
</script>
<input type="button" value="Click Me" onclick="showMessage()">
this值等于事件的目標元素
一般很少使用HTML事件處理程序,原因是它有如下幾個缺點:
- 有調(diào)用順序的要求,事件函數(shù)必須在HTML之前定義好
- 擴展事件處理程序的作用域在不同瀏覽器中會導(dǎo)致不同結(jié)果
- HTML和JavaScript代碼緊密耦合肤寝,如果要更換事件處理程序牧挣,就要改動兩個地方
DOM0級事件處理程序
var btn = document.getElementById("myBtn");
//綁定事件
btn.onclick = function() {
alert(this.id); //"myBtn"
};
//解綁事件
btn.onclick = null;
作用域:依附的元素的作用域
DOM2級事件處理程序
“DOM2級事件”定義了兩個方法,用于處理指定和刪除事件處理程序的操作:addEventListener() 和 removeEventListener()
所有節(jié)點中都包含這兩個方法醒陆,并且它們都接受3個參數(shù):要處理的事件名、作為事件處理程序的函數(shù)和一個布爾值(true表示在捕獲階段調(diào)用事件處理程序/false表示在冒泡階段調(diào)用事件處理程序)
使用DOM2級方法添加事件處理程序的主要好處是可以添加多個事件處理程序裆针,依次順序觸發(fā)
作用域:依附的元素的作用域
IE事件處理程序
IE實現(xiàn)了與DOM中類似的兩個方法:attachEvent()和detachEvent()刨摩,由于IE8及更早版本只支持事件冒泡,所以通過attachEvent()添加的事件處理程序都會被添加到冒泡階段
同addEventListener(),attachEvent()方法也可以用來為一個元素添加多個事件處理程序世吨,不同的是以相反的順序被觸發(fā)
作用域:全局作用域
跨瀏覽器的事件處理程序
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.removeHandler) {
element.removeHandler(type, handler, false);
} else if(element.detachEvent) {
element.detachEcent("on" + type, handler);
} else {
element["on" + type] =null;
}
}
};
事件對象
在觸發(fā)DOM上的某個事件時澡刹,會產(chǎn)生一個事件對象event,這個對象中包含著所有與事件有關(guān)的信息耘婚。包括導(dǎo)致事件的元素罢浇、事件的類型以及其他與特定事件相關(guān)的信息。
DOM中的事件對象
無論指定事件處理程序時使用什么方法(DOM0級或DOM2級)沐祷,都會傳入event對象嚷闭,event對象包含與創(chuàng)建它的特定事件有關(guān)的屬性和方法,觸發(fā)的事件類型不一樣赖临,可用的屬性和方法也不一樣胞锰。不過,所有事件都會有下列屬性和方法:
bubbles
cancelable
currentTarget
defaultPrevented
detail
eventPhase
preventDefault()
stopImmediatePropagation()
stopPropagation()
target
trusted
type
view
具體含義看這里
在事件處理程序內(nèi)部兢榨,對象this始終等于currentTarget的值嗅榕,而target則只包含事件的實際目標
IE中的事件對象
DOM0級:event對象作為window對象的一個屬性存在
attachEvent():event對象作為參數(shù)被傳入事件處理函數(shù)中,也可以通過window對象來訪問event對象
IE的event對象同樣也包含與創(chuàng)建它的事件相關(guān)的屬性和方法吵聪。其中很多屬性和方法都有相應(yīng)的或者相關(guān)的DOM屬性和方法凌那,但所有事件對象都會包含下列屬性和方法:
cancelBubble
returnValue
srcElement
type
跨瀏覽器的事件對象
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;
}
},
getEvent: function(event) {
return event ? event : window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function() {
if(event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
removeHandler: function(element, type, handler) {
if(element.removeHandler) {
element.removeHandler(type, handler, false);
} else if(element.detachEcent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] =null
}
},
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
};
事件類型
“DOM3級事件”規(guī)定了以下幾類事件:
- UI(User Interface,用戶界面)事件吟逝,當用戶和頁面上的元素交互時觸發(fā)帽蝶;
- 焦點事件,當元素獲取或失去焦點時觸發(fā)澎办;
- 鼠標事件嘲碱,當用戶通過鼠標在頁面上執(zhí)行操作時觸發(fā);
- 滾輪事件局蚀,當使用鼠標滾輪(或類似設(shè)備)時觸發(fā)麦锯;
- 文本時間,當在文檔中輸入文本時觸發(fā)琅绅;
- 鍵盤事件扶欣,當用戶通過鍵盤在頁面上執(zhí)行操作時觸發(fā);
- 合成事件,當為IME(Input Method Editor料祠,輸入法編輯器)輸入字符時觸發(fā)骆捧;
- 變動(mutation)事件,當?shù)讓覦OM結(jié)構(gòu)發(fā)生變化時觸發(fā)髓绽;
- 變動名稱事件敛苇,當元素或?qū)傩悦儎訒r觸發(fā)。(已廢棄)
UI事件
DOMActive
(DOM3已廢棄該事件)load
unload
abort
error
select
resize
scroll
可以使用document.implementation.hasFeature("HTMLEvents", "2.0");
來確定瀏覽器是否支持“DOM2級事件”顺呕;使用document.implementation.hasFeature("UIEvent", "3.0");
來確定是否支持“DOM3級事件”
-
load
事件
當頁面完全加載后(包括所有圖像枫攀、JavaScript文件、CSS文件等外部資源)株茶,就會觸發(fā)window上面的load事件;
<img>上面也可以觸發(fā)load事件来涨,無論是在DOM中的圖像元素還是HTML中的圖像元素。注意启盛,新圖像元素不一定要從添加到文檔后才開始下載蹦掐,只要設(shè)置了src屬性就會開始下載;
<script>元素也會觸發(fā)load事件僵闯,以便開發(fā)人員確定動態(tài)加載的JavaScript文件是否加載完畢卧抗。與圖像不同,只有在設(shè)置了<script>元素的src屬性并將該元素添加到文檔中鳖粟,才會開始下載JavaScript文件颗味。
IE和Opera還支持<link>元素上的load事件,以便開發(fā)人員確定樣式表是否加載完畢(與<script>節(jié)點類似牺弹,在未指定href屬性并將<link>元素添加到文檔之前也不會開始下載樣式表)浦马。
根據(jù)“DOM2級事件”規(guī)范,應(yīng)該在document而非window上面觸發(fā)load事件张漂。但是晶默,所有瀏覽器都在window上面實現(xiàn)了該事件,以確保向后兼容航攒。
-
unload
事件
與load事件相對磺陡,這個事件在文檔被完全卸載后觸發(fā)。而利用這個事件最多的情況是清除引用漠畜,以避免內(nèi)存泄漏币他。
既然unload事件是在一切都被卸載之后才觸發(fā),那么在頁面加載后存在的那些對象憔狞,此時就不一定存在了蝴悉。此時,操作DOM節(jié)點或者元素的樣式就會導(dǎo)致錯誤
根據(jù)“DOM2級事件”瘾敢,應(yīng)該在<body>元素而非window對象上面觸發(fā)unload事件拍冠。不過尿这,所有瀏覽器都在window上實現(xiàn)了unload事件,以確保向后兼容庆杜。
-
resize
事件
當瀏覽器窗口被調(diào)整到一個新的高度或?qū)挾葧r射众,就會觸發(fā)resize事件。
關(guān)于何時會觸發(fā)resize事件晃财,不同瀏覽器有不同的機制叨橱。IE、Safari断盛、Chrome和Opera會在瀏覽器窗口變化了1像素時就觸發(fā)resize事件雏逾,然后隨著變化不斷重復(fù)觸發(fā)。Firefox則只會在用戶停止調(diào)整窗口大小時才會觸發(fā)resize事件郑临。由于存在這個差別,應(yīng)該注意不要在這個事件的處理程序中加入大計算量的代碼屑宠,因為這些代碼有可能被頻繁的執(zhí)行厢洞,從而導(dǎo)致瀏覽器反應(yīng)明顯變慢。
瀏覽器窗口最小化或最大化時也會觸發(fā)resize事件 -
scroll
事件
雖然scroll事件是在window對象上發(fā)生的典奉,但它實際表示的則是頁面中相應(yīng)元素的變化躺翻。在混雜模式下,可以通過<body>元素的scrollLeft和scrollTop來監(jiān)控到這一變化卫玖;而在標準模式下公你,除Safari之外的所有瀏覽器都會通過<html>元素來反映這一變化(Safari仍然基于<body>跟蹤滾動位置)。
EventUtil.addHandler(window, "scroll", function(event) {
if(document.compatMode === "CSS1Compat") {
alert(document.documentElement.scrollTop);
} else {
alert(document.body.scrollTop);
}
});
焦點事件
blur
(該事件不會冒泡)DOMFocusIn
(DOM3已廢棄) DOMFocusOut
(DOM3已放棄) focus
(該事件不會冒泡) focusIn
focusOut
當焦點從頁面中的一個元素移動到另一個元素假瞬,會依次觸發(fā)下列事件:
- focusOut在失去焦點的元素上觸發(fā)陕靠;
- focusIn在獲得焦點的元素上觸發(fā);
- blur在失去焦點的元素上觸發(fā)脱茉;
- DOMFocusOut在失去焦點的元素上觸發(fā)剪芥;
- focus在獲得焦點的元素上觸發(fā);
- DOMFocusIn在獲得焦點的元素上觸發(fā)琴许。
要確定瀏覽器是否支持這些事件税肪,可以使用document.implementation.hasFeature("FocusEvent", "3.0")
即使focus和blur不冒泡,也可以在捕獲階段偵聽到它們
鼠標與滾輪事件
鼠標事件
click
dblclick
(DOM3新增) mousedown
mouseenter
(不冒泡榜田,DOM3新增) mouseleave
(不冒泡益兄,DOM3新增) mousemove
mouseout
mouseover
mouseup
只有在同一元素上相繼觸發(fā)mousedown和mouseup事件,才會觸發(fā)click事件箭券,如果mousedown和mouseup中的一個被取消净捅,就不會觸發(fā)click事件
只有觸發(fā)兩次click事件才會觸發(fā)一次dblclick事件,如果有代碼阻止了連續(xù)兩次觸發(fā)click事件(可能是直接取消click事件辩块,也可能通過取消mousedown或mouseup間接實現(xiàn))灸叼,那么就不會觸發(fā)dblclick事件了
這4個事件觸發(fā)的順序是:
- mousedown
- mouseup
- click
- mousedown
- mouseup
- click
- dblclick
要監(jiān)測瀏覽器是否支持以上DOM2級事件神汹,可以使用document.implementation.hasFeature("MouseEvents", "2.0");
,監(jiān)測是否支持DOM3級事件古今,可以使用document.implementation.hasFeature("MouseEvent", "3.0");
滾輪事件
滾輪事件只有一個mousewheel
- 客戶區(qū)坐標位置
鼠標事件都是在瀏覽器視口中的特定位置上發(fā)生的屁魏,這個位置信息保存在事件對象的clientX
clientY
注意這個值不包括頁面滾動的距離,因此這個位置并不代表鼠標在頁面上的位置 - 頁面坐標位置
頁面坐標通過事件對象的pageX和pageY屬性捉腥,能告訴你事件是在頁面中的什么位置發(fā)生的氓拼,也就是表示鼠標光標在頁面中的位置。
IE8及更早版本不支持事件對象上的頁面坐標抵碟,不過使用客戶區(qū)坐標和滾動信息(document.documentElement.srollLeft[scrollTop] || document.body.scrollLeft[scrollTop]
)可以計算出來 - 屏幕坐標位置
通過screenX和screenY屬性就可以確定鼠標事件發(fā)生時鼠標指針相對于整個屏幕的坐標信息 - 修改鍵
DOM規(guī)定了4個屬性桃漾,shiftKey、ctrlKey拟逮、altKey和metaKey(Windows鍵盤中的Windows鍵撬统,Mac上是Cmd鍵),這些屬性都是布爾值敦迄。如果相應(yīng)的鍵被按下了恋追,則值為true,否則值為false罚屋。
IE8及之前版本不支持metaKey屬性 - 相關(guān)元素
DOM通過event對象的relatedTarget屬性提供了相關(guān)元素的信息苦囱。這個屬性只對于mouseover
和mouseout
事件才包含值;對于其他事件脾猛,這個屬性的值是null
IE8及之前版本不支持relatedTarget屬性撕彤,但提供了保存著同樣信息的不同屬性。在mouseover事件觸發(fā)時猛拴,IE的fromElement屬性中保存了相關(guān)元素羹铅;在mouseout事件觸發(fā)時,IE的toElement屬性中保存著相關(guān)元素 - 鼠標事件
只有在主鼠標按鈕被點擊(或鍵盤回車鍵被按下)時才會觸發(fā)click事件愉昆,但對于mousedown和mouseup事件來說睦裳,則在其event對象存在一個button屬性,表示按下或釋放的按鈕撼唾,有3個值:0表示主鼠標按鈕廉邑,1表示中間的鼠標按鈕(鼠標滾輪按鈕),2表示次鼠標按鈕
IE8及之前版本也提供了button屬性倒谷,但這個屬性的值與DOM的button屬性有很大差異蛛蒙,有多達8種組合 - 更多的事件信息
“DOM2級事件”規(guī)范在event對象中還提供了detail屬性,用于給出有關(guān)事件的更多信息
對于鼠標事件來說渤愁,detail中包含了一個數(shù)值牵祟,表示在給定位置上發(fā)生了多少次單擊。在同一像素上相繼地發(fā)生一次mousedown和一次mouseup事件算一次單擊抖格。detail屬性從1開始計數(shù)诺苹,每次單擊后都會遞增咕晋。如果鼠標在mousedown和mouseup之間移動了位置,則detail會被重置為0
IE通過額外的5個屬性為鼠標事件提供了更多信息 - 鼠標滾輪事件
mousewheel事件可以在任何元素上面觸發(fā)收奔,最終會冒泡到document(IE8)或window(IE9掌呜、Opera、Chrome及Safari)對象
與mousewheel事件對應(yīng)的event對象除包含鼠標事件的所有標準信息外坪哄,還包含一個特殊的wheelDelta屬性(向前滾動鼠標滾輪時质蕉,wheelDelta是120的倍數(shù);向后滾動鼠標滾輪時翩肌,是-120的倍數(shù))
Opera9.5之前的版本中模暗,wheelDelta值的正負號是顛倒的
Firefox支持一個名為DOMMouseScroll的類似事件,也就是鼠標滾輪滾動時觸發(fā)念祭,并包含與鼠標事件有關(guān)的所有屬性兑宇,而有關(guān)鼠標滾輪的信息保存在detail屬性中,向前滾動鼠標滾輪時粱坤,這個屬性的值是-3的倍數(shù)隶糕,向后滾動鼠標滾輪時,是3的倍數(shù) - 觸摸設(shè)備
iOS和Android設(shè)備沒有鼠標比规,所以在面向iPhone和iPod中的Safari開發(fā)時,要記住以下幾點:
- 不支持dblclick事件拦英。雙擊瀏覽器窗口會放大畫面蜒什,而且沒有辦法改變該行為
- 輕擊可點擊元素(如鏈接或者已經(jīng)被指定了onclick事件處理程序的元素)會觸發(fā)mousemove事件。如果此操作會導(dǎo)致內(nèi)容變化疤估,將不再有其他事件發(fā)生灾常;如果屏幕沒有變化,那么會依次發(fā)生mousedown铃拇、mouseup和click事件
- mouseover事件也會觸發(fā)mouseover和mouseout事件
- 兩個手指放在屏幕上且頁面隨手指移動并滾動時會觸發(fā)mousewheel和scroll事件
- 無障礙性問題
如果你的Web應(yīng)用程序或網(wǎng)站要確保殘疾人特別是那些使用屏幕閱讀器的人都能訪問钞瀑,那么在使用鼠標事件時要格外小心。由于除click事件外的鼠標事件無法通過鍵盤來觸發(fā)慷荔,不建議使用click之外的其他鼠標事件來展示功能或引發(fā)代碼執(zhí)行
鍵盤與文本事件
- keydown:按下鍵盤上的任意鍵時觸發(fā)雕什,如果按住不放的話,會重復(fù)觸發(fā)此事件
- keypress:按下鍵盤上的字符鍵時觸發(fā)显晶,如果按住不放的話贷岸,會重復(fù)觸發(fā)此事件
- keyup:釋放鍵盤上的鍵時觸發(fā)
- textInput:文本插入文本框之前會觸發(fā)此事件
- 鍵碼
在發(fā)生keydown和keyup事件時,event對象的keyCode屬性中會包含一個代碼磷雇,與鍵盤上一個特定的鍵對應(yīng)偿警。對數(shù)字字母鍵,keyCode屬性的值與ASCII碼中對應(yīng)小寫字母或數(shù)字的編碼相同唯笙,與Shift鍵的狀態(tài)無關(guān)螟蒸。DOM和IE的event對象都支持keyCode屬性
有一些特殊情況盒使,如在Firefox和Opera中,按分號鍵時keyCode值為59七嫌,也就是ASCII中分號的編碼少办;但IE和Safari返回186,即鍵盤中按鍵的鍵碼 - 字符編碼
發(fā)生keypress事件意味著按下的鍵會影響到屏幕文本的顯示(包括插入和刪除)抄瑟。IE9凡泣、Firefox、Chrome和Safari的event對象都支持一個charCode屬性皮假,這個屬性只有在發(fā)生keypress事件時才包含值(該鍵所代表的ASCII編碼)鞋拟,此時的keyCode通常為0或者也可能等于所按鍵的鍵碼(IE8及之前版本和Opera的keyCode中存的是ASCII編碼) - DOM3變化
- DOM3級事件中的鍵盤事件不再包含charCode屬性,而是包含兩個新屬性:key(字符鍵:相應(yīng)文本字符惹资,非字符鍵:鍵名)和char(字符鍵:相應(yīng)文本字符贺纲,非字符鍵:null);
- 添加了location屬性(表示按下了什么位置的鍵);
- 為event對象添加了getModifierState(要檢測的修改鍵)方法诫欠,如果指定的修改鍵處于被按下的狀態(tài)尤勋,這個方法返回true,否則返回false
由于存在跨瀏覽器的問題懈叹,不推薦使用這些特性
- textInput事件
“DOM3級事件”規(guī)范中引入了一個新事件,名叫textInput
該事件與keypress主要有如下幾個區(qū)別:
- 前者只有在可編輯區(qū)域才能觸發(fā)分扎,而后者在任何可以獲得焦點的元素上都可以觸發(fā)
- 前者只會在按下能夠輸入實際字符的鍵時才會出發(fā)澄成,而后者在按下那些能夠影響文本顯示的鍵時也會觸發(fā)(例如:退格鍵)
textInput事件的event對象中還包含一個data屬性,表示輸入的字符(而非字符編碼)畏吓,IE9+墨状、Safari和Chrome均支持;還包含一個inputMethod屬性菲饼,表示把文本輸入到文本框中的方式肾砂,只有IE支持該屬性
- 設(shè)備中的鍵盤事件
任天堂Wii會在用戶按下遙控器上的按鍵時觸發(fā)鍵盤事件。
iOS版Safari和Android版WebKit在使用屏幕鍵盤是會觸發(fā)鍵盤事件宏悦。
復(fù)合事件
復(fù)合事件是DOM3級事件中新添加的一類事件镐确,用于處理IME(輸入法編輯器,可以讓用戶輸入在物理鍵盤上找不到的字符)的輸入序列饼煞。IME通常需要同時按住多個鍵辫塌,但最終只輸入一個字符。復(fù)合事件就是針對這種檢測和處理這種輸入而設(shè)計的派哲。
復(fù)合事件有三種:compositionstart
compositionupdate
compositionend
另外臼氨,它比文本事件的事件對象多一個屬性data
IE9+是唯一支持該事件的瀏覽器,要確定瀏覽器是否支持復(fù)合事件芭届,可以使用document.implementation.hasFeature("CompositionEvent", "3.0");
變動事件
DOM2級的變動(mutation)事件能在DOM中的某一部分發(fā)生變化時給出提示储矩,DOM2級定義了如下變動事件:
- DOMSubtreeModified:在DOM結(jié)構(gòu)中發(fā)生任何變化時觸發(fā)感耙。這個事件在其他任何事件觸發(fā)后都會觸發(fā);
- DOMNodeInserted:在一個節(jié)點作為子節(jié)點被插入到另一個節(jié)點中時觸發(fā)持隧;
- DOMNodeRemoved:在節(jié)點從其父節(jié)點中被移除時觸發(fā)即硼;
- DOMNodeInsertedIntoDocument:在一個節(jié)點被直接插入文檔或通過子樹間接插入文檔之后觸發(fā)。這個事件在DOMNodeInserted之后觸發(fā)屡拨;
- DOMNodeRemovedFromDocument:在一個節(jié)點被直接從文檔中移除或通過子樹間接從文檔中移除之前觸發(fā)只酥。這個事件在DOMNodeRemoved之后觸發(fā);
- DOMAttrModified:在特性被修改之后觸發(fā)呀狼;
- DOMCharacterDataModified:在文本節(jié)點的值發(fā)生變化時觸發(fā)
通過document.implementation.hasFeature("MutationEvents", "2.0");
檢測瀏覽器是否支持變動事件
IE8及更早版本不支持任何變動事件
- 刪除節(jié)點
刪除一個節(jié)點變化事件執(zhí)行順序
- 被刪除元素上觸發(fā)DOMNodeRemoved事件裂允,relatedNode屬性為其父節(jié)點;
- 被刪除元素上觸發(fā)DOMNodeRemovedFromDocument事件哥艇;
- 被刪除元素的每個子節(jié)點上觸發(fā)DOMNodeRemovedFromDocument事件绝编;
- 在被刪除元素的父節(jié)點上觸發(fā)DOMSubtreeModified事件
- 插入節(jié)點
插入一個節(jié)點變化事件執(zhí)行順序
- 被插入元素上觸發(fā)DOMNodeInserted事件,relatedNode屬性為其父節(jié)點貌踏;
- 被插入元素上觸發(fā)DOMNodeInsertedIntoDocument事件十饥;
- 在被插入元素的父節(jié)點上觸發(fā)DOMSubtreeModified事件
HTML5事件
- contextmenu事件
表示何時應(yīng)該顯示上下文菜單,以便取消默認的上下文菜單從而提供自定義的菜單祖乳,下例的代碼實現(xiàn)了自定義的上下文菜單:
<div id="myDiv">右鍵</div>
<ul id="myMenu" style="position:absolute;visibility:hidden;background-color:silver;">
<li><a >site1</a></li>
<li><a >site2</a></li>
<li><a >site3</a></li>
</ul>
EventUtil.addHandler(window, "load", function(event) {
var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "contextmenu", function() {
EventUtil.preventDefault(); // 保證不顯示瀏覽器默認的上下文菜單
var menu = document.getElementById("myMenu");
menu.style.left = event.clientX + "px";
menu.style.top = event.clientY + "px";
menu.style.visibility = "visible";
});
// 單擊隱藏菜單
EventUtil.addHandler(document, "click", function(event) {
document.getElementById("myMenu").style.visibility = "hidden";
});
});
支持contextmenu事件的瀏覽器有IE逗堵、Firefox、Safari眷昆、Chrome和Opera 11+
- beforeunload事件
這個事件會在瀏覽器卸載頁面之前觸發(fā)蜒秤,可以通過它來取消卸載并繼續(xù)留在原有頁面
EventUtil.addHandler(window, "beforeunload", function(event) {
event = EventUtil.getEvent(event);
var message = "I'm really going to miss you if you go.";
event.returnValue = message; // 對于IE和Firefox而言,必須將event.returnValue的值設(shè)置為要顯示給用戶的字符串
return message; // 對于Safari和Chrome而言隙赁,必須將要顯示給用戶的字符串作為函數(shù)的值返回
});
Opera 11及之前的版本不支持beforeunload事件
- DOMContentLoaded事件
window的load事件會在頁面中的一切都加載完畢時觸發(fā)垦藏,而DOMContentLoaded事件則在形成完整的DOM樹之后就會觸發(fā)梆暖,不理會圖像伞访、JavaScript文件、CSS文件或其他資源是否已經(jīng)下載完畢轰驳。與load事件不同厚掷,DOMContentLoaded支持在頁面下載的早期添加事件處理程序,這也就意味著用戶能夠盡早地與頁面進行交互级解。
DOMContentLoaded事件對象不會提供任何額外的信息(其target屬性是document)
對于不支持DOMContentLoaded的瀏覽器冒黑,建議在頁面加載期間設(shè)置一個時間為0毫秒的超時調(diào)用(在當前JS處理完成后立即運行這個函數(shù)),為了確保盡可能與DONContentLoaded被觸發(fā)的時間盡可能同步勤哗,必須將其作為頁面中的第一個超時調(diào)用(即便如此抡爹,也還是無法保證在所有環(huán)境中該超時調(diào)用一定會早于load事件被觸發(fā))。 - readystatechange事件
IE為DOM文檔中的某些部分提供了readystatechange事件芒划,為了提供與文檔或元素加載有關(guān)的信息冬竟,但這個事件的行為有時候也很難預(yù)料欧穴。支持readystatechange事件的每個對象都有一個readyState屬性,可能包含下列5個值中的一個:uninitialized
loading
loaded
interactive
complete
這個事件的event對象不會提供任何信息泵殴,也沒有目標對象
對于document而言涮帘,值為"interactive"的readyState會在與DOMContentLoaded大致相同的時刻觸發(fā)readystatechange事件;在與load事件一起使用時笑诅,無法預(yù)測兩個事件觸發(fā)的先后順序
支持readystatechange事件的瀏覽器有IE调缨、Firefox 4+和Opera
<script>(在IE和Opera中)和<link>(僅IE中)元素也會觸發(fā)readystatechange事件,可以用來確定外部的JavaScript和CSS文件是否已經(jīng)加載完成吆你,下面展示了一段加載外部JavaScript文件的代碼
EventUtil.addHandler(window, "load", function() {
var script = document.createElement("script");
EventUtil.addHandler(script, "readystatechange", function(event) {
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
// 如果進入loaded或complete任何一個階段弦叶,都可以表示資源可用,則移除事件處理函數(shù)(以防止被執(zhí)行兩次)
if(target.readyState == "loaded" || target.readyState == "complete") {
EventUtil.removeHandler(target, "readystatechange", arguments.callee);
alert("Script Loaded");
}
});
script.src = "example.js";
document.body.appendChild(script);
});
最重要的是要一并檢測readyState的兩個狀態(tài)早处,并在調(diào)用了一次事件處理程序后就將其移除
- pageshow和pagehide事件
Firefox和Opera有一個特性湾蔓,名叫“往返緩存”(back-forward cache,或bfcache)砌梆,可以在用戶使用瀏覽器的“后退”和“前進”按鈕時加快頁面的轉(zhuǎn)換速度默责。如果頁面位于bfcache中,那么再次打開該頁面時就不會觸發(fā)load事件咸包,但為了更形象地說明bfcache的行為桃序,F(xiàn)irefox還是提供了一些新事件
第一個事件就是pageshow,這個事件在頁面顯示時觸發(fā)烂瘫,無論是否來自bfcache媒熊。來自非bfcache的頁面會在load事件觸發(fā)后觸發(fā);而對于來自bfcache的頁面坟比,會在頁面狀態(tài)完全恢復(fù)的那一刻觸發(fā)
雖然這個事件的目標是document芦鳍,但必須將其事件處理程序添加到window
除了通常的屬性之外,pageshow事件的event對象還包含一個名為persisted布爾值屬性葛账,標識頁面是否被保存在了bfcache中
與pageshow事件對應(yīng)的是pagehide事件柠衅,該事件會在瀏覽器卸載頁面的時候觸發(fā),而且是在unload事件之前觸發(fā)籍琳。這個事件的特性與pageshow相同菲宴,不同點是persisted屬性的用途,標識頁面卸載之后是否被保存在bfcache中
Firefox趋急、Safari 5+喝峦、Chrome和Opera均支持這兩個事件,IE9及之前版本不支持這兩個事件 - hashchange事件
HTML5新增haschange事件呜达,標識URL的參數(shù)列表是否發(fā)生變化
必須要在hashchange事件處理程序添加給window對象谣蠢,然后URL參數(shù)列表只要變化就會調(diào)用它,此時的event對象應(yīng)該額外包含兩個屬性:oldURL和newURL,這兩個屬性分別保存著參數(shù)列表變化前后的完整URL
支持該事件的瀏覽器有IE8+眉踱、Firefox 3.6+勋颖、Safari 5+、Chrome和Opera 10.6+勋锤,在這些瀏覽器中饭玲,只有Firefox 6+、Chrome和Opera支持oldURL和newURL屬性叁执,為此茄厘,最好使用location對象來確定當前的參數(shù)列表
可以使用("onhashchange" in window) && (document.documentMode === undefined || document.documentMode > 7)
(如果IE8是在IE7文檔模式下運行,即使功能失效也會返回true)來確定是否支持該事件
設(shè)備事件
- orientationchange事件
蘋果公司為移動Safari中添加了該事件谈宛,以便確定設(shè)備何時由橫向查看模式切換為縱向查看模式
window.orientation屬性中可能包含3個值:
0 表示肖像模式
90 表示向左旋轉(zhuǎn)的橫向模式(home鍵在右)
-90 表示向右旋轉(zhuǎn)的橫向模式(home鍵在左)
180 表示iPhone頭朝下(這種模式至今尚未得到支持)
所有iOS設(shè)備都支持orientationchange事件和window.orientation - MozOrientation事件
Firefox 3.6為檢測設(shè)備的方向引入了一個名為MozOrientation的新事件次哈,當設(shè)備的加速計檢測到設(shè)備方向改變時,就會觸發(fā)這個事件吆录,該事件在window對象上觸發(fā)
該事件對象包含3屬性:x窑滞、y和z
這幾個屬性的值都介于1到-1之間,表示不同坐標軸上的方向
在靜止狀態(tài)下恢筝,x值為0哀卫,y值為0,z值為1(表示設(shè)備處于豎直狀態(tài))
如果設(shè)備向右傾斜撬槽,x值會減写烁摹;反之侄柔,向左傾斜共啃,x值會增大
類似地,如果設(shè)備向遠離用戶的方向傾斜暂题,y值會減小移剪,向接近用戶的方向傾斜,y值會增大
z軸檢測垂直加速度薪者,1表示靜止不動纵苛,在設(shè)備移動時值會減小(失重狀態(tài)下為0)
只有帶加速計的設(shè)備才支持該事件 - deviceorientation事件
與MozOrientation事件類似啸胧,它也是在加速計檢測到設(shè)備方向變化時在window對象上觸發(fā)赶站,而且具有與MozOrientation事件相同的支持限制幔虏,不過纺念,該事件主要意圖是告訴開發(fā)人員設(shè)備在空間中朝向哪兒,而不是如何移動
設(shè)備在三維空間中是靠x想括、y和z軸來定位的陷谱。當設(shè)備靜止放在水平表面上時,這三個值都是0。x軸方向是從左往右烟逊,y軸方向是從下往上渣窜,z軸方向是從后往前,參見下圖:
該事件觸發(fā)時,事件對象包含5個屬性:alpha
beta
gamma
absolute
compassCalibrated
支持該事件的瀏覽器有iOS 4.2+中的Safari、Chrome和Android版WebKit - devicemotion事件
該事件是要告訴開發(fā)人員設(shè)備什么時候移動谎倔,而不僅僅是設(shè)備方向如何改變饥悴。例如,通過該屬性能夠檢測到設(shè)備是不是正在往下掉绿映,或者是不是被走著的人拿在手里库车。
觸發(fā)該事件時,事件對象包括以下屬性:acceleration
accelerationIncludingGravity
interval
rotationRate
支持該事件的瀏覽器有iOS 4.2+中的Safari裆泳、Chrome和Android版WebKit
觸摸與手勢事件
- 觸摸事件
- touchstart:當手指觸摸屏幕時觸發(fā)叹洲;即使已經(jīng)有一個手紙放在了屏幕上也會觸發(fā);
- touchmove:當手指在屏幕上滑動時連續(xù)地觸發(fā)晾虑。在這個事件發(fā)生期間疹味,調(diào)用preventDefault()可以阻止?jié)L動;
- touchend:當手指從屏幕上移開時觸發(fā)帜篇;
- touchcancel:當系統(tǒng)停止跟蹤觸摸時觸發(fā)(確切觸發(fā)時間糙捺,文檔中沒有明確說明)
這幾個事件都會冒泡,也可以取消笙隙。雖然沒有在DOM規(guī)范中定義洪灯,但它們卻是以兼容DOM的方式實現(xiàn)的。因此竟痰,每個觸摸事件的event對象都提供了在鼠標事件中常見的屬性:bubbles签钩、cancelable、view坏快、clientX铅檩、clientY、screenX莽鸿、screenY昧旨、detail、altKey祥得、shiftKey兔沃、ctrlKey和metaKey
除了常見的DOM屬性外,觸摸事件還包括下列三個用于跟蹤觸摸的屬性: - touches:表示當前跟蹤的觸摸操作的Touch對象的數(shù)組
- targetTouches:特定于事件目標的Touch對象的數(shù)組
- changeTouches:表示自上次觸摸以來發(fā)生了什么改變的Touch對象的數(shù)組
每個Touch對象包含了下列屬性: - clientX:觸摸目標在視口中的x坐標级及;
- clientY:觸摸目標在視口中的y坐標乒疏;
- identifier:標識觸摸的唯一ID;
- pageX:觸摸目標在頁面中的x坐標饮焦;
- pageY:觸摸目標在頁面中的y坐標怕吴;
- screenX:觸摸目標在屏幕中的x坐標;
- screenY:觸摸目標在屏幕中的y坐標县踢;
- target:觸摸的DOM節(jié)點目標
這些事件在元素上發(fā)生的順序如下:
(1) touchstart
(2) mouseover
(3) mousemove
(4) mousedown
(5) mouseup
(6) click
(7) touchend
支持觸摸事件的瀏覽器包括iOS版Safari械哟、Android版WebKit、bada版Dolfin殿雪、OS6+中的BlackBerry WebKit暇咆、Opera Mobile 10.1+和LG專有OS中的Phantom瀏覽器。目前只有iOS版Safari支持多點觸摸丙曙。桌面版Firefox 6+和Chrome也支持觸摸事件
- 手勢事件
當兩個手指觸摸屏幕時就會產(chǎn)生手勢爸业,手勢通常會改變顯示項的大小,或者旋轉(zhuǎn)顯示項
- gesturestart:當一個手指已經(jīng)按在屏幕上而另一個手指又觸摸屏幕時觸發(fā)亏镰;
- gesturechange:當觸摸屏幕的任何一個手指的位置發(fā)生變化時觸發(fā)扯旷;
- gestureend:當任何一個手指從屏幕上面移開時觸發(fā)
只有兩個手指都觸摸到事件的接收容器時才會觸發(fā)這些事件。當一個手指放在屏幕上時索抓,會觸發(fā)touchstart事件钧忽,如果另一個手指又放在了屏幕上毯炮,則會先觸發(fā)gesturestart事件,隨后觸發(fā)基于該手指的touchstart事件耸黑。如果一個或兩個手指在屏幕上滑動桃煎,將會觸發(fā)gesturechange事件。但只要有一個手指移開大刊,就會觸發(fā)gestureend事件为迈,緊接著又會觸發(fā)基于該手指的touchend事件
與觸摸事件一樣,每個手勢事件的event對象都包含著標準的鼠標事件屬性缺菌,此外還包含兩個額外的屬性:rotation和scale葫辐,前者表示手指變化引起的旋轉(zhuǎn)角度,負值表示逆時針旋轉(zhuǎn)伴郁,正值表示順時針旋轉(zhuǎn)(該值從0開始)耿战;后者表示兩個手指間距離的變化情況(例如向內(nèi)收縮會縮短距離);這個值從1開始焊傅,并隨距離拉大而增大昆箕,隨距離縮短而減小
內(nèi)存和性能
事件使用不當會導(dǎo)致很多性能問題,
首先租冠,每個函數(shù)都是對象鹏倘,都會占用內(nèi)存;內(nèi)存中對象越多顽爹,性能就越差纤泵;
其次,必須事先指定所有事件處理程序而導(dǎo)致的DOM訪問次數(shù)镜粤,會延遲整個頁面的交互就緒時間捏题。
從如何利用好事件處理程序的角度出發(fā),還是有一些方法能夠提升性能的
事件委托
對“事件處理程序過多”問題的解決方案就是事件委托
事件委托利用冒泡肉渴,只指定一個事件處理程序公荧,就可以管理某一類型的所有事件。
如果可行的話同规,可以考慮為document對象添加一個事件處理程序循狰,用以處理頁面上發(fā)生的某種特定類型的事件。這樣做與采取傳統(tǒng)的做法相比具有如下優(yōu)先:
- document對象很快就可以訪問券勺,而且可以在頁面生命周期的任何時間點上為它添加事件處理程序(無需等待DOMContentLoaded或load事件)绪钥;
- 在頁面中設(shè)置事件處理程序所需的時間更少。只添加一個事件處理程序所需的DOM引用更少关炼,所花的時間也更少程腹;
- 整個頁面占用的內(nèi)存空間更少,能夠提升整個性能
最適合采用事件委托技術(shù)的事件包括click儒拂、mousedown寸潦、mouseup色鸳、keydown、keyup和keypress见转。雖然mouseover和mouseout事件也冒泡命雀,但是適當處理它們并不容易,而且經(jīng)常需要計算元素的位置
移除事件處理程序
每當將事件處理程序指定給元素時池户,運行中的瀏覽器代碼與支持頁面交互的JavaScript代碼之間就會建立一個連接咏雌。這種連接越多凡怎,頁面執(zhí)行起來就越慢校焦。如前所述,可以采用事件委托技術(shù)统倒,限制連接數(shù)量寨典。另外,在不需要的時候移除事件處理函數(shù)房匆,也是解決這個問題的一種方案耸成。內(nèi)存中留有那些過時不用的“空事件處理程序”,也是造成Web應(yīng)用程序內(nèi)存與性能問題的主要原因浴鸿。
在兩種情況下井氢,可能會造成上述問題。
第一種情況就是從文檔中移除帶有事件處理程序的元素時岳链。這可能是通過純粹的DOM操作(removeChild()和replaceChild()方法)花竞,但更多地是發(fā)生在使用innerHTML替換頁面中的某一部分的時候。最好的做法就是在移除元素之前先移除事件處理程序掸哑。
第二種情況是卸載頁面的時候约急。IE8及更早版本在這種情況是問題比較多,其他瀏覽器或多或少也有類似問題苗分。最好的做法就是在頁面卸載之前厌蔽,先通過onunload事件處理程序移除所有事件處理程序。
注意摔癣,使用onunload事件處理程序意味著頁面不會被緩存在bfcache中
模擬事件
可以使用JavaScript在任意時刻來觸發(fā)特定的事件奴饮,而此時的事件就如同瀏覽器創(chuàng)建的事件一樣,這些事件該冒泡還會冒泡择浊,而且照樣能夠?qū)е聻g覽器執(zhí)行已經(jīng)指定的處理它們的事件處理程序拐云。為此,DOM2級規(guī)范為此規(guī)定了模擬特定事件的方式近她,IE9叉瘩、Opera、Firefox粘捎、Chrome和Safari都支持這種方式薇缅。IE有它自己模擬事件的方式危彩。
DOM中的事件模擬
可以在document對象上使用createEvent()方法創(chuàng)建event對象。這個方法接受一個參數(shù)泳桦,即表示要創(chuàng)建的事件類型的字符串汤徽。在DOM2級中,所有這些字符串都使用英文復(fù)數(shù)形式灸撰,而在DOM3級中都變成了單數(shù)谒府。這個字符串可以是下列幾個字符串之一。
- UIEvents:一般化的UI事件浮毯。鼠標事件和鍵盤事件都繼承自UI事件完疫。DOM3級中時UIEvent;
- MouseEvents:一般化的鼠標事件债蓝。DOM3級中是MouseEvent壳鹤;
- MutationEvents:一般化的DOM變動事件。DOM3級中是MutationEvent饰迹;
- HTMLEvents:一般化的HTML事件芳誓。沒有對應(yīng)的DOM3級事件(HTML事件被分散到其他類別中)。
在創(chuàng)建了event對象之后啊鸭,還需要使用與事件有關(guān)的信息對其進行初始化锹淌。每種類型的event對象都有一個特殊的方法,為它傳入適當?shù)臄?shù)據(jù)就可以初始化該event對象赠制。
模擬事件的最后一步是就是觸發(fā)事件赂摆。這一步需要使用dispatchEvent()方法,所有支持事件的DOM節(jié)點都支持這個方法憎妙。調(diào)用dispatch方法時库正,需要傳入一個參數(shù),即表示要觸發(fā)事件的event對象厘唾。
- 模擬鼠標事件
創(chuàng)建新的鼠標事件對象并為其指定必要的信息褥符,就可以模擬鼠標事件。創(chuàng)建鼠標事件對象的方法是為createEvent()傳入字符串"MouseEvents"抚垃。返回的對象有一個名叫initMouseEvent()方法喷楣,用于指定與該鼠標事件有關(guān)的信息。這個方法接收15個參數(shù)鹤树,分別與鼠標事件中每個典型的屬性一一對應(yīng)铣焊。
var btn = document.querySelector("myBtn");
// 創(chuàng)建事件對象
var event = document.createElement("MouseEvents");
// 初始化事件對象(參數(shù)含義 [type][bubbles][cancelable][view][detail][screenX][screenY][clientX][clientY][ctrlKey][altKey][shiftKey][metaKey][button][relatedTarget])
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
// 觸發(fā)事件
btn.dispatchEvent(event);
- 模擬鍵盤事件
DOM3級規(guī)定,調(diào)用createEvent()并傳入"KeyboardEvent"就可以創(chuàng)建一個鍵盤事件罕伯。返回的事件對象會包含一個initKeyEvent()方法曲伊。
由于DOM3級不提倡使用keypress事件,因此只能利用這種技術(shù)來模擬keydown和keyup事件。
var textbox = document.getElementById("myTextbox"),
event;
// 以DOM3級方式創(chuàng)建事件對象
if(document.implementation.hasFeature("KeyboardEvents", "3.0")) {
event = document.createEvent("KeyboardEvent");
// 初始化事件對象(參數(shù)含義[type][bubbles][cancelable][view][key][location][modifiers][repeat])
event.initKeyboardEvent("keydown", true, true, document.defaultView, "a", 0, "Shift", 0);
}
// 觸發(fā)事件
textbox.dispatchEvent(event);
在Firfox中坟募,調(diào)用createEvent()并傳入"KeyEvents"就可以創(chuàng)建一個鍵盤事件岛蚤。返回的事件對象會包含一個initKeyEvent()方法,這個方法接受10個參數(shù)(type懈糯、bubbles涤妒、cancelable、view赚哗、ctrlKey她紫、altKey、shiftKey屿储、metaKey贿讹、keyCode、charCode)扩所。將創(chuàng)建的event對象傳入到dispatchEvent()方法就可以觸發(fā)鍵盤事件
// 只適用于Firefox
var textbox = document.getElementById("myTextbox");
// 創(chuàng)建事件對象
var event = document.createEvent("KeyEvents");
// 初始化事件對象
event.initKeyEvent("keypress", true, true, document.defaultView, false, false, false, false, 65, 65);
// 觸發(fā)事件
textbox.dispatchEvent(event);
在其他瀏覽器中围详,則需要創(chuàng)建一個通用的事件朴乖,然后再向事件對象中添加鍵盤事件特定的信息
var textbox = document.getElementById("Events");
// 創(chuàng)建事件對象
var event = document.createEvent("Events");
// 初始化事件對象
event.initEvent(type, bubbles, cancelable);
event.view = document.defaultView;
event.altKey = false;
event.ctrlKey = false;
event.shiftKey = false;
event.metaKey = false;
event.keyCode = 65;
event.charCode = 65;
// 觸發(fā)事件
textbox.dispatchEvent(event);
- 模擬其他事件
要模擬變動事件祖屏,可以使用createEvent("MutationEvents")創(chuàng)建一個包含initMutationEvent()方法的變動事件對象。這個方法接受的參數(shù)包括:type买羞、bubbles袁勺、cancelable、relatedNode畜普、preValue期丰、newValue、attrName和attrChange
// 以下代碼模擬了DOMInserted事件
var event = document.createEvent("MutationEvents");
event.initMutationEvent("DOMNodeInserted", true, false, someNode, "", "", "", 0);
target.dispatchEvent(event);
- 自定義DOM事件
DOM3級還定義了“自定義事件”吃挑。自定義事件不是由DOM觸發(fā)的钝荡,它的目的是讓開發(fā)人員創(chuàng)建自己的事件。要創(chuàng)建新的自定義事件舶衬,可以調(diào)用createEvent("CustomEvent")埠通。返回對象有一個名為initCustomEvent()的方法,接收如下4個參數(shù):type逛犹、bubbles端辱、cancelable、detail虽画。
var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "myevent", function(event) {
alert("DIV:" + event.detail);
});
EventUtil.addHandler(document, "myevent", function(event) {
alert("DOCUMENT:" + event.detail);
});
if(document.implementation.hasFeature("CustomeEvents", "3.0")) {
event = document.createEvent("CustomEvent");
event.initCustomEvent("myevent", true, false, "Hello world!");
div.dispatchEvent(event);
}
支持自定義DOM事件的瀏覽器有IE9+和Firefox 6+
IE中的事件模擬
在IE8及之前版本中模擬事件與在DOM中模擬事件的思路相似:先創(chuàng)建event對象舞蔽,然后為其指定相應(yīng)的信息,然后再使用該對象來觸發(fā)事件码撰。當然渗柿,IE在實現(xiàn)每個步驟時都采用了不一樣的方式。
調(diào)用document.createEventObject()方法可以在IE中創(chuàng)建event對象脖岛。但與DOM方式不同的是朵栖,這個方法不接受參數(shù)砾省,結(jié)果會返回一個通用event對象。然后混槐,你必須手工為這個對象添加必要的信息(沒有方法來輔助完成這一步驟)编兄。最后一步就是在目標上調(diào)用fireEvent()方法,這個方法接受兩個參數(shù):事件處理程序的名稱和event對象声登。在調(diào)用fireEvent()方法時狠鸳,會自動為event對象添加srcElement和type屬性;其他屬性則都是必須通過手工添加的悯嗓。換句話說件舵,模擬任何IE支持的事件都采用相同的模式。
var btn = document.getElementById("myBtn");
// 創(chuàng)建事件對象
var event = document.createEventObject();
// 初始化事件對象
event.screenX = 100;
event.screenY = 0;
event.clientX = 0;
event.clientY = 0;
event.ctrlKey = false;
event.altKey = false;
event.shiftKey = false;
event.button = 0;
// 觸發(fā)事件
btn.fireEvent("onclick", event);
注意:這里可以為對象隨意添加屬性脯厨,不會有任何限制——即使添加的屬性IE8及更早版本并不支持頁無所謂铅祸。在此添加的屬性對事件沒有什么影響,因為只有事件處理程序才會用到它們
文末附上事件的腦圖: