HTML事件

轉載:http://jiangzhengjun.javaeye.com/blog/480996


事件

DOM同時支持兩種事件模式:捕獲型事件和冒泡型事件,但是,捕獲型事件先發生。兩種事件流會觸及DOM中的所有對象,從document對象開 始,也在document對象結束(大部分兼容標準的瀏覽會繼續將事件捕獲/冒泡延續至window對象),DOM中的元素都會連續收到兩次事件,一次在 捕獲過程中,另一次在冒泡過程中。DOM事件模型最獨特的性質是,文本節點也觸發事件(在IE中不會)。點擊文本節點事件流應該如下圖:


 
傳統事件處理函數有兩種分配方式:在JavaScript中或者在HTML中。


在JavaScript中分配事件處理函數:

Js代碼
  1. var  oDiv = document.getElementById( "div1" );  
  2. oDiv.onclick = function  () {  
  3.     alert("I was clicked" );  
  4. };  

 
注:在這個分配方法,事件處理函數名稱必須小寫,才能正確響應事件。
在HTML中分配事件處理函數:

Html代碼
  1. < div   onclick = 'alert("I was clicked")' >   </ div >    
<div onclick='alert("I was clicked")'> </div> 

 
說明:用這種方法,事件處理函數的大小寫可任意,所以onclick等同於onClick、OnClick或ONCLICK,但標準的事 件處理函數應該全部用小寫定義。
說明:傳統分配方式有個缺陷就是隻能分配一個處理函數。於是就出現了其它以下分配方式。

 

IE中特有的attachEvent()事件處理函數分配方 式:

Js代碼
  1. var  fnClick1 =  function  () {  
  2.     alert("Clicked!" );  
  3. };  
  4. var  fnClick2 =  function  () {  
  5.     alert("Also clicked!" );  
  6. };  
  7. var  oDiv = document.getElementById( "div" );  
  8. oDiv.attachEvent("onclick" , fnClick1); //綁定事件處理函數    
  9. oDiv.attachEvent("onclick" , fnClick2);   
  10. //do something ...    
  11. oDiv.detachEvent("onclick" , fnClick1); //解除事件處理函數    
  12. oDiv.detachEvent("onclick" , fnClick2);  

 
說明:事件處理函數總是按照添加它們的順序進行調用。

 

DOM中的事件處理函數綁定
DOM 中方法addEventListener()和removeEventListener()用來分配與移除事件處理函數。與IE不同,需三個參數:事件 名、要分配的處理函數、處理函數是用於冒泡階段還是捕獲階段,如果是捕獲階段,第三個參數爲true。

Js代碼
  1. var  fnClick1 =  function  () {  
  2.     alert("Clicked!" );  
  3. };  
  4. var  oDiv = document.getElementById( "div" );  
  5. oDiv.addEventListener("onclick" , fnClick1,  false ); //綁定事件處 理函數   
  6. //do something ...    
  7. oDiv.removeEventListener("onclick" , fnClick1,  false ); //解除事件處 理函數    

 說明:也可綁定多個函數,但要注意的是第三個參數刪除時 要與添加時一樣才能真真刪除掉函數 ,否則刪除不掉,也不會報錯。
傳統方式oDiv.onclick = fnClick;oDiv.addEventListener('onclick',fnClick1,false); 等 價。  

事件對象的屬性與方法

鼠標 / 鍵盤屬性

 

屬性

描述

IE

F

O

W3C

altKey

返回當事件被觸發時, "ALT" 是否被按下。

6

1

9

Yes

button

返回當事件被觸發時,哪個鼠標按鈕被點擊。

6

1

9

Yes

clientX

鼠標指針相對於當前窗口的水平座標。

6

1

9

Yes

clientY

鼠標指針相對於當前窗口的垂直座標。

6

1

9

Yes

ctrlKey

返回當事件被觸發時, "CTRL" 鍵是否被按 下。

6

1

9

Yes

metaKey

返回當事件被觸發時, "meta" 鍵是否被按 下。

No

1

9

Yes

relatedTarget

對於 mouseover 事件來 說,該屬性是鼠標指針移到目標節點上時所離開的那個節點。對於 mouseout 事件來 說,該屬性是離開目標時,鼠標指針進入的節點。

No

1

9

Yes

screenX

事件發生時鼠標指針相對於屏幕的水平座標。

6

1

9

Yes

screenY

鼠標指針相對於屏幕的垂直座標。

6

1

9

Yes

shiftKey

返回當事件被觸發時, "SHIFT" 鍵是否被按 下。

6

1

9

Yes

IE 屬性

除了上面的鼠標 / 事件屬性, IE 瀏 覽器還支持下面的屬性:

 

屬性

描述

cancelBubble

如果事件句柄想阻止事件傳播到包容對象,必須把該屬性設爲 true

fromElement

對於 mouseover mouseout 事 件, fromElement 引用移出鼠標的元素。

keyCode

對於 keypress 事件,該 屬性聲明瞭被敲擊的鍵生成的 Unicode 字符編碼。對於 keydown keyup 事 件,它指定了被敲擊的鍵的虛擬鍵盤代碼。虛擬鍵盤碼可能和使用的鍵盤的佈局相關。

offsetX,offsetY

發生事件的地點在事件源元素的座標系統中的 x 坐 標和 y 座標。

returnValue

如果設置了該屬性,它的值比事件句柄的返回值優先級高。把這個屬性設置爲 fasle , 可以取消發生事件的源元素的默認動作。

srcElement

對於生成事件的 Window 對象、 Document 對 象或 Element 對象的引用。

toElement

對於 mouseover mouseout 事 件,該屬性引用移入鼠標的元素。

x,y

事件發生的位置的 x 座標和 y 坐 標,它們相對於用 CSS 動態定位的最內層包容元素。

 

 

標準 Event 屬性

下面列出了 2 DOM 事 件標準定義的屬性。

 

屬性

描述

IE

F

O

W3C

bubbles

如果事件是起泡類型,則返回 true ,否則返回 fasle

No

1

9

Yes

cancelable

如果用 preventDefault() 方 法可以取消與事件關聯的默認動作,則爲 true ,否則爲 fasle

No

1

9

Yes

currentTarget

返回其監聽器觸發事件的節點,即當前處理該事件的元素、文檔或窗口。在捕獲和起泡階 段,該屬性是非常有用的,因爲在這兩個節點,它不同於 target 屬性。

No

1

9

Yes

eventPhase

回事件傳播的當前階段。它的值是 1 2 3 三 個常量之一,它們分別表示捕獲階段、正常事件派發和起泡階段。

 

 

 

Yes

target

返回事件的目標節點(觸發該事件的節點),如生成事件的元素、文檔或窗口。

No

1

9

Yes

timeStamp

返回事件生成的日期和時間。

No

1

9

Yes

type

返回發生的事件的類型,即當前 Event 對象表示的事 件的名稱。

它與註冊的事件句柄同名,或者是事件句柄屬性刪除前綴 "on" 比 如 "submit" "load" "click"

6

1

9

Yes

 

標準 Event 方法

下面列出了 2 DOM 事 件標準定義的方法。 IE 的事件模型不支持這些方法:

 

方法

描述

IE

F

O

W3C

initEvent()

初始化新創建的 Event 對象的屬性。

No

1

9

Yes

preventDefault()

通知瀏覽器不要執行與事件關聯的默認動作。

No

1

9

Yes

stopPropagation()

終止事件在傳播過程的捕獲、目標處理或起泡階段進一步傳播。調用該方法後,該節點上處理該事件的處 理程序將被調用,事件不再被分派到其他節點。

No

1

9

Yes

 

 

 

 

事件對象

包含的信息如下:
引 起事件的對象、事件發生時鼠標的信息、事件發生時鍵盤的信息。


事件對象只在發生事件時才被創建,且只有事件處理函數才能訪問。處理完畢就會被銷燬。

 

IE中,事件對象是window對象的一個屬性event。 採用如下方式進行訪問:

Js代碼
  1. oDiv.onclick =  function  () {  
  2.     var  oEvent = window.event;  
  3. };  

 
DOM標準中,event對象必須作爲唯一參數傳 給事件處理函數,如下訪問:

Js代碼
  1. oDiv.onclick =  function  () {  
  2.     var  oEvent = arguments[0];  
  3. };  

 
當然此種方式可以直接通過參數傳遞進來:

Js代碼
  1. oDiv.onclick =  function (oEvent){ //...}    

 

IE與DOM獲取事件屬性相同的地方:

1、 獲取事件類型(名稱)

Js代碼
  1. function  handleEvent(oEvent) {  
  2.     if  (oEvent.type ==  "click" ) {  
  3.         alert("clicked" );  
  4.     } else  {  
  5.         if  (oEvent.type ==  "mouseover" ) {  
  6.             alert("mouse over" );  
  7.         }  
  8.     }  
  9. }  
  10. oDiv.onclick = handleEvent;  
  11. oDiv.onmouseover = handleEvent;  

 
2、 獲取按鍵代碼(keydown/keyup事件)

Js代碼
  1. var  iKeyCode = oEvent.keyCode;   

 

 3、 檢測是否按下了Shift、Alt、Ctrl鍵

Js代碼
  1. var  bShift = oEvent.shiftKey;   
  2. var  bAlt = oEvent.altKey;   
  3. var  bCtrl = oEvent.ctrlKey;   

 
4、 獲取客戶端鼠標事件座標

Js代碼
  1. var  iClientX = oEvent.clientX;   
  2. var  iClientY = oEvent.clientY;   

 
說明:指與瀏覽器邊界距離。


5、 獲取鼠標距屏幕邊沿座標

Js代碼
  1. var  iScreenX = oEvent.screenX;   
  2. var  iScreenY = oEvent.screenY;   

 

IE與DOM獲取事件屬性不同的地方:

1、 獲取目標(事件源)
IE:

Js代碼
  1. var  oTarget = oEvent.srcElement;   

 
DOM:

Js代碼
  1. var  oTarget = oEvent.target;   

 2、 獲取字符代碼
IE 和DOM都支持event對象的keyCode屬性,它會返回按下的按鍵的數值代碼。但如果按鍵代表一個字符(但非Shift、Ctrl、Alt 等),IE的keyCode將返回字符的代碼(等於它的Unicode值):

Js代碼
  1. var  iCharCode = oEvent.keyCode;   

 在DOM兼容的瀏覽器中,按鍵代碼與按鍵字符是分開的,要獲取字符代碼,請使用charCode屬性:

Js代碼
  1. var  iCharCode = oEvent.charCode;   

 
如果不確定按下的按鍵是否包含字符,則可使用isChar屬性來進行判斷:

Js代碼
  1. if (oEvent.isChar){   
  2.     var  iCharCode = oEvent.charCode;   
  3. }   

 
最後可以用這個值來獲得實際的字符,只要使用String.fromCharCode()方法:

Js代碼
  1. var  sChar = String.fromCharCode(iCharCode);   

 

3、 阻止事件發生
IE:

Js代碼
  1. oEvent.returnValue =  false ;   

 Mozilla:

Js代碼
  1. oEvent.preventDefault();   

 例如:附上使用上下文件菜單

Js代碼
  1. document.body.oncontextmenu =  function  (oEvnet) {  
  2.     if  (isIE) {  
  3.         oEvnet = window.event;  
  4.         oEvnet.returnValue = false ;  
  5.     } else  {  
  6.         oEvnet.preventDefault();  
  7.     }  
  8. };  

 
4、 停止事件冒泡
IE:

Js代碼
  1. oEvent.cancelBubble =  true ;   

 Mozilla:

Js代碼
  1. oEvent.stopPropagation();   

 
如下停止事件傳播示例:

Html代碼
  1. < html   onclick = "alert('html')" >   
  2.     < head >   
  3.         < title > Event Propagation Example </ title >   
  4.         < script   type = "text/javascript"   src = "detect.js" >   </ script >   
  5.         < script   type = "text/javascript" >    
  6.             function handleCick(oEvent) {  
  7.                 alert("input");  
  8.                 if (isIE) {  
  9.                     oEvent.cancelBubble  =  true ;  
  10.                 } else {  
  11.                     oEvent.stopPropagation();  
  12.                 }  
  13.             }  
  14.         </ script >   
  15.     </ head >   
  16.     < body   onclick = "alert('body')" >   
  17.         < input   type = 'button'   value = 'Click Me'   onclick = "handleCick (event)"   />   
  18.     </ body >   
  19. </ html >   
<html onclick="alert('html')">
	<head>
		<title>Event Propagation Example</title>
		<script type="text/javascript" src="detect.js"> </script>
		<script type="text/javascript"> 
			function handleCick(oEvent) {
				alert("input");
				if (isIE) {
					oEvent.cancelBubble = true;
				} else {
					oEvent.stopPropagation();
				}
			}
		</script>
	</head>
	<body onclick="alert('body')">
		<input type='button' value='Click Me' onclick="handleCick (event)" />
	</body>
</html>

 

事件的類型

DOM標準定義了以下幾組事件:

鼠標事件、鍵盤事件、HTML事件(窗口發生變動或者發生特定客戶與服務器交互時觸發)、突變事件(底層DOM結構發生改變時觸發)


鼠標鍵盤事件
要 觸發dblclick事件,在同一個目標上要按順序發生以下事件:

mousedown、mouseup、click、mousedown、mouseup、click、dblclick

 

mouseout:用戶正要將其移出元素的邊界時發生。
mouseover:移入到某元素上時發生。
mousemove:鼠標 在某個元素移動時發生。


用戶按一次某字符按鍵 時,會按以下發生事件:keydown、keypress、keyup


如果按某非字符鍵 (如Shift),按以下發生事件:keydown、keyup


如果用戶按下一個字符按鍵且不放 ,keydown和keypress事件將逐個持續觸發,直 到鬆開。

 
如果用戶按下一個非字符按鍵且不放 ,將只有keydown事件持續觸發。

HTML元素事件

load事件——頁面完全載入後,在window對象上觸發;所有的框架都載入後,在框架上集上觸發; <img/>完全載入後,在其上觸發;或者對於 <object/>元素,當其完全載入後在其上觸發。


unload——頁面完全卸載後,在window對象上觸發;所有的框架都卸載後,在框架上集上觸發; <img/>完全卸載後,在其上觸發;或者對於 <object/>元素,當其完全卸載後在其上觸發。


abort(異常中斷)事件——用戶停止下載過程時,如果 <object/>對象還未完全載入,就在其上觸發。


error事件——JavaScript腳本出錯時,在window對象上觸發;某個 <img/>的指定圖像無法載入時,在其上觸發;或 <object/>元素無法載入時觸發;或都框架集中的一個或多個框架無法載入時觸發。


select事件——用戶選擇了文本框中的一個或多個字符時觸發( <input/>或者 <textarea/>)。


change事件——文本框( <input/>或者 <textarea/>)失去焦點時並且在它獲取焦點後內容發生過改變時觸發;某個 <select/>元素的值發生改變時觸發。


submit事件——點擊提交按鈕( <input type="submit"/>)時,在 <form/>上觸發。


reset事件——點擊重置按鈕( <input type="reset"/>)時,在 <form/>上觸發。


resize事件——窗口或者框架的大小發生改變時觸發。


scrool事件——用戶在任何帶滾動條的元素上滾動它時觸發。


focus事件——任何元素或者窗口本身獲取焦點時觸發。


blur事件——任何元素或者窗口本身失去焦點時觸發。

load、unload事件
對於window對象可用 兩種方法定義onload事件處理函數:
第一種:window.onload=function(){//...}
第二種: <body onload='alert()'/>
這兩種是相同的,因爲在HTML中沒有window標籤,所以就加在 <body/>元素上了。


注:不要使用document.body.onload=function(){//...},如果把腳本放在 <head/>標籤中,運行還會出錯,顯示document.body未定義,所以最後用window.onload

 

在窗口關閉到下一個頁面獲取控制之前,只有很短的時間來執行事件處理函數的代碼,所以最好避免使用onunload事件處理函數。

跨平臺的事件腳本

Js代碼
  1. /*    
  2.  * fileName:eventutil.js    
  3.  */     
  4. var  EventUtil =  new  Object;  
  5. //添加事件處理函數   
  6. EventUtil.addEventHandler = function  (oTarget, sEventType, fnHandler) {  
  7.     if  (oTarget.addEventListener) { //如果是支持DOM兼容瀏覽器   
  8.       //false 表示在冒泡階段捕獲   
  9.         oTarget.addEventListener(sEventType, fnHandler, false );  
  10.     } else  {  
  11.         if  (oTarget.attachEvent) { //如果是IE   
  12.             oTarget.attachEvent("on"  + sEventType, fnHandler);  
  13.         } else  { //其他瀏覽器   
  14.             oTarget["on"  + sEventType] = fnHandler;  
  15.         }  
  16.     }  
  17. };  
  18. //刪除事件處理函數   
  19. EventUtil.removeEventHandler = function  (oTarget, sEventType, fnHandler) {  
  20.     if  (oTarget.removeEventListener) {  
  21.         oTarget.removeEventListener(sEventType, fnHandler, false );  
  22.     } else  {  
  23.         if  (oTarget.detachEvent) {  
  24.             oTarget.detachEvent("on"  + sEventType, fnHandler);  
  25.         } else  {  
  26.             oTarget["on"  + sEventType] =  null ;  
  27.         }  
  28.     }  
  29. };  
  30. //格式化event對象:把IE的event對象適配成DOM類似的事件對象。注:該方法不單獨使用,僅供後面的 getEvent()方法使用   
  31. EventUtil.formatEvent = function  (oEvent) {  
  32.     if  (isIE && isWin) {  
  33.          //由於IE所按的字符的編碼是包含在keyCode屬性中,所以如果事件類型是keypress,   
  34.          //需要創建charCode屬性,值等於keyCode,否則爲其他類型事件時設置成0   
  35.         oEvent.charCode = (oEvent.type == "keypress" ) ? oEvent.keyCode : 0;  
  36.         oEvent.eventPhase = 2;//這個屬性始終等於2代表冒泡階段,因爲IE公支持這個階段   
  37.         oEvent.isChar = (oEvent.charCode > 0);//當charCode不爲0時爲true   
  38.         oEvent.pageX = oEvent.clientX + document.body.scrollLeft;//鼠標距頁面邊的距離   
  39.         oEvent.pageY = oEvent.clientY + document.body.scrollTop;  
  40.         oEvent.preventDefault = function  () { // 阻止事件適配 IE->DOM   
  41.             this .returnValue =  false ;  
  42.         };  
  43.          //relatedTarget爲DOM事件中的第二個事件目標   
  44.         if  (oEvent.type ==  "mouseout" ) {  
  45.               //鼠標移出時爲toElement(移向的那個對象)   
  46.             oEvent.relatedTarget = oEvent.toElement;  
  47.         } else  {  
  48.             if  (oEvent.type ==  "mouseover" ) {  
  49.               //鼠標移進時爲fromElement(從哪個對象移進來的)   
  50.                 oEvent.relatedTarget = oEvent.fromElement;  
  51.             }  
  52.         }  
  53.          //阻止事件冒泡   
  54.         oEvent.stopPropagation = function  () {  
  55.             this .cancelBubble =  true ;  
  56.         };  
  57.          //事件源適配   
  58.         oEvent.target = oEvent.srcElement;  
  59.         oEvent.time = (new  Date).getTime();  
  60.     }  
  61.     return  oEvent;  
  62. };  
  63.   
  64. //該函數在事件處理函數中使用   
  65. EventUtil.getEvent = function  () {  
  66.     if  (window.event) {  
  67.         return   this .formatEvent(window.event);  
  68.     } else  {  
  69.     /*函數是一個對象,event對象是一個函數,每個函數都有一個caller屬性,它包含了指向調用它的方法  
  70.       的引用。如,funcA()調用funcB(),那麼funcB.caller就等於funcA。假設某 個事件處理函數調用了  
  71.      EventUtil.getEvent(), 那麼EventUtil.getEvent.caller就指向這個事件處理函數的本身。  
  72.      又函數有arguments屬性,而event對象總是事件處理函數的第一個參數*/   
  73.         return  EventUtil.getEvent.caller.arguments[0];  
  74.     }  
  75. };  

 

 

Html代碼
  1. < html >   
  2.     < head >   
  3.         < title > Mouse Events Example </ title >   
  4.         < script   type = "text/javascript"   src = "detect.js" > </ script >   
  5.         < script   type = "text/javascript"   src = "eventutil.js" > </ script >   
  6.         < script   type = "text/javascript" >   
  7.           
  8.             EventUtil.addEventHandler(window, "load", function () {  
  9.                 var oDiv  =  document .getElementById("div1");  
  10.                   
  11.                 EventUtil.addEventHandler(oDiv, "mouseover", handleEvent);  
  12.                 EventUtil.addEventHandler(oDiv, "mouseout", handleEvent);  
  13.                 EventUtil.addEventHandler(oDiv, "mousedown", handleEvent);  
  14.                 EventUtil.addEventHandler(oDiv, "mouseup", handleEvent);  
  15.                 EventUtil.addEventHandler(oDiv, "click", handleEvent);  
  16.                 EventUtil.addEventHandler(oDiv, "dblclick", handleEvent);                  
  17.                   
  18.             });  
  19.               
  20.             function handleEvent() {  
  21.                 var oEvent  =  EventUtil .getEvent();//通過EventUtil的 getEvent()方法獲取IE中適配後的事件對象  
  22.   
  23.                 var oTextbox  =  document .getElementById("txt1");  
  24.                 oTextbox.value += "/n> " + oEvent.type;  
  25.                 //oEvent.target 其實是IE屬性裏的srcElement屬性  
  26.                 oTextbox.value += "/n    target is " + oEvent.target.tagName;  
  27.                 if (oEvent.relatedTarget) {  
  28.                     //IE 事件對象中本沒有relatedTarget屬性,是由fromElement或toElement適配而來  
  29.                     oTextbox.value += "/n    relatedTarget is " + oEvent.relatedTarget.tagName;  
  30.                 }  
  31.             }  
  32.      
  33.         </ script >   
  34.     </ head >   
  35.     < body >   
  36.         < p >   
  37.             Use your mouse to click and double click the red square.  
  38.         </ p >   
  39.         < div   style = "width: 100px; height: 100px; background-color: red"   
  40.             id = "div1" > </ div >   
  41.         < p >   
  42.             < textarea   id = "txt1"   rows = "15"   cols = "50" > </ textarea >   
  43.         </ p >   
  44.     </ body >   
  45. </ html >   
<html>
	<head>
		<title>Mouse Events Example</title>
		<script type="text/javascript" src="detect.js"></script>
		<script type="text/javascript" src="eventutil.js"></script>
		<script type="text/javascript">
        
            EventUtil.addEventHandler(window, "load", function () {
                var oDiv = document.getElementById("div1");
                
                EventUtil.addEventHandler(oDiv, "mouseover", handleEvent);
                EventUtil.addEventHandler(oDiv, "mouseout", handleEvent);
                EventUtil.addEventHandler(oDiv, "mousedown", handleEvent);
                EventUtil.addEventHandler(oDiv, "mouseup", handleEvent);
                EventUtil.addEventHandler(oDiv, "click", handleEvent);
                EventUtil.addEventHandler(oDiv, "dblclick", handleEvent);                
                
            });
            
            function handleEvent() {
                var oEvent = EventUtil.getEvent();//通過EventUtil的getEvent()方法獲取IE中適配後的事件對象

                var oTextbox = document.getElementById("txt1");
                oTextbox.value += "/n>" + oEvent.type;
                //oEvent.target其實是IE屬性裏的srcElement屬性
                oTextbox.value += "/n    target is " + oEvent.target.tagName;
                if (oEvent.relatedTarget) {
                	//IE事件對象中本沒有relatedTarget屬性,是由fromElement或toElement適配而來
                    oTextbox.value += "/n    relatedTarget is " + oEvent.relatedTarget.tagName;
                }
            }
   
        </script>
	</head>
	<body>
		<p>
			Use your mouse to click and double click the red square.
		</p>
		<div style="width: 100px; height: 100px; background-color: red"
			id="div1"></div>
		<p>
			<textarea id="txt1" rows="15" cols="50"></textarea>
		</p>
	</body>
</html>

 

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