Event
對象
Event
對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。一旦事件發生,便會生成Event
對象,如單擊一個按鈕,瀏覽器的內存中就產生相應的 event
對象。
- 事件通常與函數結合使用,函數不會在事件發生前被執行!
event
對象只在事件發生的過程中才有效。event
的某些屬性只對特定的事件有意義。比如,fromElement
和toElement
屬性只對onmouseover
和onmouseout
事件有意義。
firefox
裏的event
跟IE裏的不同,IE裏的是全局變量,隨時可用;firefox
裏的要用參數引導才能用,是運行時的臨時變量。
在IE/Opera
中是window.event
,在Firefox
中是event
;而事件的對象,在IE中是 window.event.srcElement
,在Firefox中是event.target
,Opera中兩者都可用。
Event
對象屬性和方法
clientX,clientY
:返回當事件被觸發時,鼠標指針相對於瀏覽器窗口可視文檔區域的左上角的的水平x座標和垂直y座標;screenX,screenY
:返回當某個事件被觸發時,鼠標指針相對於顯示器左上角的水平x座標和垂直y座標;offsetX,offsetY/layerX,layerY
:事件發生的時候,鼠標相對於源元素左上角的位置;x,y/pageX,pageY
:事件發生的位置的 x 座標和 y 座標,它們相對於用CSS動態定位的最內層包容元素;altKey,ctrlKey,metaKey,shiftKey
:返回當事件被觸發時,”ALT”、”TRL”、”meta”、”SHIFT”
鍵是否被按下;keyCode
:返回keydown
和keyup
事件發生的時候按鍵的代碼,以及keypress
事件的Unicode
字符(firefox2不支持event.keycode
,可以用event.which
替代 );button
:返回當onmousedown, onmouseup
, 和onmousemove
事件被觸發時,哪個鼠標按鈕被點擊。對其他事件,不管鼠標狀態如何,都返回0
(比如onclick
)。整數,1
代表左鍵,2
代表右鍵,4
代表中鍵,如果按下多個鍵,酒把這些值加起來,所以3就代表左右鍵同時按下(firefox中0
代表左鍵,1
代表中間鍵,2
代表右鍵);
可能的值:0 沒按鍵 1 按左鍵 2 按右鍵 3 按左右鍵 4 按中間鍵 5 按左鍵和中間鍵 6 按右鍵和中間鍵 7 按所有的鍵
type
:事件的類型,如onlick
中的click
;srcElement/target
:事件源,就是發生事件的元素;relatedTarget
:返回與事件的目標節點相關的節點;fromElement,toElement
:對於mouseover
和mouseout
事件,fromElement
引用移出鼠標的元素,toElement
引用移入鼠標的元素;currentTarget
:返回其事件監聽器觸發該事件的元素;timeStamp
:返回事件生成的日期和時間;eventPhase
:返回事件傳播的當前階段,1表示捕獲階段,2表示處於目標,3表示冒泡階段;detail
:表示的是與事件相關的細節信息bubbles
:返回布爾值,指示事件是否是起泡事件類型;cancelable
:返回布爾值,表示是否可以取消事件的默認行爲;cancelBubble
:一個布爾屬性,默認是false
。把它設置爲true
的時候,將阻止事件進一步起泡到包容層次的元素;(e.cancelBubble= true;
相當於e.stopPropagation();
)returnValue
:一個布爾屬性,設置爲false
的時候可以阻止瀏覽器執行默認的事件動作;(e.returnValue =false;
相當於e.preventDefault();
)defaultPrevented
:表示是否調用了preventDefault()
initEvent(eventType,canBubble,cancelable)
:初始化新創建的Event
對象的屬性;preventDefault()
: 通知瀏覽器不要執行與事件關聯的默認動作;stopPropagation()
:不再派發事件;attachEvent(eventType, fn)
,detachEvent()/addEventListener(事件類型, 回調函數,事件機制),removeEventListener
:爲制定DOM對象事件類型註冊多個事件處理函數的方法,它們有兩個參數,第一個是事件類型,第二個是事件處理函數。事件機制分爲冒泡和捕獲,如果爲false
表示事件冒泡,爲true
表示事件捕獲。在attachEvent()
事件執行的時候,this
關鍵字指向的是window
對象,而不是發生事件的那個元素;
事件冒泡和事件捕獲
事件流是描述從頁面中接收事件的順序**【從內到外(冒泡),從外到內(捕獲)】**。
事件冒泡:事件可以沿着包容層次一點點起泡到上層,也就是說,下層的DOM節點定義的事件處理函數,到了上層的節點如果還有和下層相同事件類型的事件處理函數,那麼上層的事件處理函數也會執行。例如, div
標籤包含了 a
,如果這兩個標籤都有onclick
事件的處理函數,那麼執行的情況就是先執行標籤 a
的onclick
事件處理函數,再執行 div
的事件處理函數。如果希望的事件處理函數執行完畢之後,不希望執行上層的 div
的onclick
的事件處理函數了,那麼就把cancelBubble
設置爲true
即可。
事件捕獲和事件冒泡剛好相反,它是事件從最不具體的節點(document
)先接收到事件,然後再向下逐一捕獲至(文檔中嵌套層次最深的那個點【當前綁定事件的那個元素】)。
簡單地說,事件冒泡和事件捕獲都是一種事件傳遞的機制。這種機制可以使事件在不同級的元素間傳遞。事件冒泡是從事件觸發的源節點,向父節點傳遞,直到到達最頂節點。而事件捕獲則是從最頂節點,逐步向下傳遞,直到到達事件觸發的源節點。
DOM事件流如圖(剪自javascript高級程序設計):
由圖可知捕獲過程要先於冒泡過程
Event
對象的一些兼容性寫法
- 獲得event對象兼容性寫法
event || (event = window.event);
- 獲得
target
兼容型寫法
event.target||event.srcElement
- 阻止瀏覽器默認行爲兼容性寫法
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
- 阻止冒泡寫法
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
event
事件的傳遞與冒泡處理示例
html:
<div>
<table nclick="gotClick(event,'table',this)" id="table">
<tr nclick="gotClick(event,'tr',this)" id="tr">
<td nclick="gotClick(event,'td',this)" id="td">
<input type="button" name="button" value="單擊我"
onclick="gotClick(event,'按鈕',this);" id="button">
</td>
</tr>
</table>
</div>
<div id='result'>
</div>
js:
function gotClick(event,msg,obj){
var msgs = msg+" => 被單擊了!<br/>";
var object = event.target||event.srcElement;
document.getElementById('result').innerHTML +=msgs;
// event.cancelBubble=true;//阻止傳遞
}
運行結果是:
按鈕 => 被單擊了!
td => 被單擊了!
tr => 被單擊了!
table => 被單擊了!
事件監聽
addEventListener()
與removeEventListener()
用於處理指定和刪除事件處理程序操作。
它們都接受3個參數:如addEventListener("事件名" , "事件處理函數" , "布爾值");
(注:事件名不含”on
”,如”click
”)
現在的版本可以省略第三個參數,默認值爲false
,表示在冒泡階段調用事件處理程序。如果爲true
,則表示在捕獲階段調用事件處理程序。
示例:
要在body
上添加事件處理程序,可以使用下列代碼:
document.body.addEventListener('touchmove', function (event) {
event.preventDefault();
},false);
通過addEventListener()
添加的事件處理程序只能使用removeEventListener()
來移除;移除時傳入的參數與添加處理程序時使用的參數相同。這也意味着通過addEventListener()
添加的匿名函數無法移除。
錯誤用法示例:
document.body.addEventListener('touchmove', function (event) {
event.preventDefault();
},false);
document.body.removeEventListener('touchmove', function (event) {
event.preventDefault();
},false);
這個例子中,使用addEventListener()
添加一個事件處理程序。雖然調用removeEventListener()
是看似使用了相同的參數,但實際上,第二個參數與傳入addEventListener()
中的那一個完全不同的函數。而傳入removeEventListener()
中的事件處理程序函數必須與傳addEventListener()
中的相同
正確用法示例:
function bodyScroll(event){
event.preventDefault();
}
document.body.addEventListener('touchmove',bodyScroll,false);
document.body.removeEventListener('touchmove',bodyScroll,false);
重寫後的這個例子在addEventListener()
和removeEventListener()
中用的是相同的函數。
共用函數不能帶參數,錯誤用法示例:
function bodyScroll(event){
event.preventDefault();
}
document.body.addEventListener('touchmove',bodyScroll(),false);
document.body.removeEventListener('touchmove',bodyScroll(),false);
總結:
1:相同事件綁定和解除,需要使用共用函數;綁定和解除事件時,事件沒有”on”,即onclick
寫成click
2:共用函數不能帶參數;