JS Event對象詳解

Event對象

Event 對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。一旦事件發生,便會生成Event對象,如單擊一個按鈕,瀏覽器的內存中就產生相應的 event對象。

  • 事件通常與函數結合使用,函數不會在事件發生前被執行!
  • event對象只在事件發生的過程中才有效。
  • event的某些屬性只對特定的事件有意義。比如,fromElementtoElement 屬性只對 onmouseoveronmouseout 事件有意義。

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:返回keydownkeyup事件發生的時候按鍵的代碼,以及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:對於 mouseovermouseout 事件,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事件的處理函數,那麼執行的情況就是先執行標籤 aonclick事件處理函數,再執行 div 的事件處理函數。如果希望的事件處理函數執行完畢之後,不希望執行上層的 divonclick的事件處理函數了,那麼就把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:共用函數不能帶參數;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章