事件流
事件流描述的是從頁面中接受事件的順序,在IE中的事件流是事件冒泡纽乱,在Netscape的事件流是事件捕獲流幸缕。
事件冒泡
IE的事件流叫做事件冒泡悔详,即事件開始是由最具體的元素接受涵亏,然后逐級向上傳播到較不具體的節(jié)點(文檔)宰睡。有的瀏覽器會跳過body元素直接冒泡到document上,有些瀏覽器還會一直冒泡到window對象上气筋〔鹉冢基本上所有的瀏覽器都支持事件冒泡。事件捕獲
Netscape提出另外一種事件流是事件捕獲裆悄,事件捕獲的思想是首先不太具體的節(jié)點應該更早的接受到事件矛纹,而具體的節(jié)點應該最后接收到事件臂聋。事件捕獲的用意在于在事件到達預定目標之前捕獲它光稼。
在IE9,Safari孩等,chrome艾君,opera,F(xiàn)irefox中也都支持事件捕獲流肄方,DOM2級事件要求事件從document開始傳播冰垄,但這些瀏覽器還是從window對象開始捕獲事件。
注:一些老版本的瀏覽器并不支持事件捕獲权她,所以我們可以放心的使用事件冒泡虹茶。
- DOM事件流
DOM2級事件規(guī)定事件流包括:事件捕獲階段逝薪,處于目標階段,事件冒泡階段蝴罪。注意董济,事件捕獲階段中,事件還是不會到目標元素上要门,目標元素上發(fā)生的事件可以看做是事件冒泡的一部分虏肾。
注意:在IE9,Safari欢搜,chrome封豪,F(xiàn)irefox,opera9.5等瀏覽器都會在事件捕獲階段觸發(fā)事件對象上的事件炒瘟。
事件處理程序
關于在文檔中響應某種事件的函數(shù)我們把稱作事件處理程序(事件偵聽器)吹埠,事件處理程序的名稱以on開頭,為事件指定處理程序的方式有以下幾種:
- HTML事件處理程序
<input type='button' onclick='alert("hello world")'>
function show(){
alert('hello world')
}
<input type='button' onclick='show()'>
這樣指定事件處理程序有一些特別的地方疮装。第一藻雌,這樣創(chuàng)建一個封裝著元素屬性值的函數(shù),這個函數(shù)中有個局部變量event斩个,也就是事件對象
<input type='button' onclick='alert(event.type)'>
//這樣你不用自己定義它胯杭,用不用從函數(shù)的參數(shù)列表中去獲取
第二,在這個函數(shù)內(nèi)部受啥,this值等于事件的目標元素:
<input type='button' onclick='alert(this)'>
以這種方式綁定事件處理程序有以下三個缺點:
- 時差問題做个,當事件執(zhí)行時,事件處理程序還未定義滚局;
- 擴展處理程序的作用域鏈在不同瀏覽器中導致不同的結(jié)果居暖;
- HTML代碼和JS代碼耦合太強,不符合結(jié)構藤肢,樣式太闺,行為分離的標準;
- DOM0級事件處理程序
通過JavaScript指定事件處理程序嘁圈,就是將一個函數(shù)賦值給一個事件處理程序?qū)傩允÷睢R褂肑avaScript指定事件處理程序,首先必須取得一個要操作的對象的引用最住。
var btn = document.getElementById('myBtn')
btn.onclick = function(){
alert('hello world')
}
使用DOM0級方法指定事件處理程序被認為是元素的方法钞澳。因此,這時候事件處理程序是在元素的作用域中運行涨缚。換句話說轧粟,程序中的this引用當前元素。
也可以刪除通過DOM0級方法指定的事件處理程序:
btn.onclick = null
- DOM2級事件處理程序
DOM2級事件,該級別事件中定義了兩個方法兰吟,用于指定和刪除事件處理程序的操作:
- addEventListener()
- removeEventListener()
所有DOM節(jié)點都包含這個兩個方法通惫,都接受三個參數(shù): - 要處理的事件名
- 事件處理程序的函數(shù)
- 布爾值(true表示在捕獲階段調(diào)用該事件處理程序,false表示冒泡階段調(diào)用)
var btn = document.getElementById('btn')
btn.addEventListener('click', function(){
alert('hello')
}, false)
同DOM0級事件一樣混蔼,這里添加的事件處理程序也是在其依附的元素的作用域中運行讽膏。
var btn = document.getElementById('btn')
btn.addEventListener('click', function(){
alert(1)
},false)
btn.addEventListener('click', function(){
alert(2)
},false)
如上,通過DOM2級事件綁定方法拄丰,可以綁定多個事件處理程序函數(shù)府树,它會一一的執(zhí)行,但是通過DOM0級只能綁定一個事件處理程序料按,如果寫第二個則會覆蓋掉前一個奄侠。
通過addEventListener綁定的事件可以通過removeEventListener來移除,移除時傳入的參數(shù)和綁定事件處理程序參數(shù)相同(注意:如果通過addEventListener綁定的匿名函數(shù)無法移除)载矿,如下可以正常解除:
var fn = function(){
alert(1)
}
var btn = document.getElementById('btn')
btn.addEventListener('click', fn, false)
btn.removeEventListener('click', fn, false) //移除
- IE事件處理程序
IE中實現(xiàn)與DOM中類似的兩個方法:
- attachEvent()
- detachEvent()
這兩個方法接受相同的兩個參數(shù): - 事件名稱
- 事件處理程序函數(shù)
var btn = document.getElementById('btn')
btn.attachEvent('onclick', function(){
alert(1)
})
//注意:這里的事件名稱前面要加on
注意: 使用attachEvent方法垄潮,事件處理程序函數(shù)的執(zhí)行環(huán)境是在全局作用域下,和DOM0級不一樣闷盔。所以在該函數(shù)中的this指向的是window
在看以下情況弯洗,attachEvent方法也可以為一個元素綁定多個事件處理函數(shù):
var btn = document.getElementById('btn')
btn.attachEvent('onclick', function(){
alert(1)
})
btn.attachEvent('onclick', function(){
alert(2)
})
執(zhí)行以上代碼,可以發(fā)現(xiàn)逢勾,執(zhí)行的順序和addEventListener的執(zhí)行順序是相反的牡整。
detachEvent方法就不詳細介紹了,用法和removeEventListener相對應的溺拱。