Welcome! 登入 註冊
美寶首頁 美寶百科 美寶論壇 美寶落格 美寶地圖

Advanced

Browser 的 JavaScript - 滑鼠事件( Mouse Event )

Browser 的 JavaScript - 滑鼠事件( Mouse Event )

分類標籤: 程式設計
本文章討論 javascript 的「滑鼠事件」,主要分別以下列「動作」來探討相關「事件」的發生順序

(一)滑鼠按一下:相關的「事件」有 onMouseDown,onMouseUp,onClick
(二)滑鼠連按二下 :相關的「事件」有onMouseDown,onMouseUp,onClick,onDblClick
(三)滑鼠移動:相關的事件為 onMouseOver,onMouseMove,onMouseOut
(四)滑鼠拖曳:相關的事件為 ( onMouseDown ), onDragStart ,( onMouseMove ),onDragEnd

並藉由 javascript 程式來實測,程式畫面如下,
本程式事件測試的對像為中間的圖片,
相關事件的發生會顯示在左邊空白處



程式內容附在文章最後。

所測試的瀏器版本為

IE9
FireFox 14.0.1
Google Chrome 21.0.1180.77
Opera 12.01
Safari 5.1.7

如果不想看中間的文章,可直接拉到最下面看整理


(一)滑鼠按一下:相關「事件」有 onMouseDown,onMouseUp,onClick

在 IE 中,如果「以滑鼠按一下中間的圖片」,「事件出現的順序」如下面左側文字所顯示:




也就是,當滑鼠按一下中間的圖片時,事件出現的順序為

onMouseDown --> onMouseUp --> onClick

這樣的順序在下列瀏覽器的結果都一樣:

IE9
FireFox 14.0.1
Google Chrome 21.0.1180.77
Opera 12.01
Safari 5.1.7



(二)滑鼠連按二下 :相關的「事件」有onMouseDown,onMouseUp,onClick,onDblClick

這種情形,IE9 和其它四種藰覽器出現的事件不太一樣,IE9 少了兩個事件 onMouseDown 及 onClick

因此,我們分以下兩種情形來討論

(1)

FireFox 14.0.1
Google Chrome 21.0.1180.77
Opera 12.01
Safari 5.1.7

因為,這四種瀏覽器結果都一樣,在此,我們便以 FireFox 為例

FireFox 的結果如下圖:




也就是當滑鼠在圖片上連按二下 時,事件出現的順序為



onMouseDown --> onMouseUp --> onClick --> onMouseDown --> onMouseUp --> onClick --> onDblClick

也就是 原來按一下的事件 重複兩次 最後 再多一個 onDblClick
加個括號 變成這樣

( onMouseDown --> onMouseUp --> onClick ) --> ( onMouseDown --> onMouseUp --> onClick ) --> onDblClick

這樣看起來很合理,比較怪的是 IE

(2) IE9

IE 9 的結果 如下圖:



發生順序為:


onMouseDown --> onMouseUp --> onClick --> onMouseUp --> onDblClick

也就是第二次只有 onMouseUp

兩種放在一起比較為



FireFox:onMouseDown --> onMouseUp --> onClick --> ( onMouseDown ) --> onMouseUp --> ( onClick ) --> onDblClick
IE: onMouseDown --> onMouseUp --> onClick --> onMouseUp --> onDblClick



(三)滑鼠移動:相關的事件為 onMouseOver,onMouseMove,onMouseOut

這個動作也是 IE 跟別人不一樣,不過只有一點點不一樣,因此我們也分兩種情形討論

(1)

FireFox 14.0.1
Google Chrome 21.0.1180.77
Opera 12.01
Safari 5.1.7

因為,這四種瀏覽器結果都一樣,在此,我們便以 FireFox 為例

如果把滑鼠從外面移動進圖片範圍,再移動出來,FireFox 的結果如下圖:



事件發生的順序為

onMouseOver --> onMouseMove -> onMouseMove -> ........ onMouseMove -> onMouseOut

也就是

(a)滑鼠剛進入圖片範圍的時候會發生 onMouseOver

(b) 在圖片範圍中移動的時候會發生 一堆 onMouseMove,發生幾次 看你移動了多久

(c) 從圖片範圍中 移動出來時會發生 onMouseOut


我們可以加上括號如下:

( onMouseOver ) --> ( onMouseMove -> onMouseMove -> ........ -> onMouseMove ) -> ( onMouseOut )

這三個括號分別代表上面說明的 (a) (b) (c)


這樣也很合理




(2)IE 9

在 IE9 中,如果把滑鼠從外面移動進圖片範圍,再移動出來,結果如下圖:




所以大致是跟其他瀏覽器一樣,不同的是,在一開始進入圖片範圍的時候會先發生「一次」onMouseMove,才發生 onMouseOver

順序如下

onMouseMouse --> onMouseOver --> onMouseMove -> onMouseMove -> ........ onMouseMove -> onMouseOut

很怪吧,一定會先發生一次 onMouseMove

如果加上括號,就如下面所示

( onMouseMouse --> onMouseOver ) --> ( onMouseMove -> onMouseMove -> ........ -> onMouseMove ) -> ( onMouseOut )



(3)另外值得一提的是,如果把滑鼠移到圖片範圍內以後,滑鼠不再動(把手移開)



IE 和 google Chrome 還會很慢的出現 onMouseMove 的事件 (明明滑鼠沒有 move )

其他三種 FireFox,Opera,Safari 則不會出現 onMouseMove 的事件

( 以上測試是 同一台電腦 同一隻滑鼠 同一隻手 同一個桌面 )


或許 IE 和 google Chrome 對 onMouseMove 的偵測是比較敏感的





(四)滑鼠拖曳:相關的事件為 ( onMouseDown ), onDragStart ,( onMouseMove ),onDragEnd

上面加括號的事件代表有的覽瀏器不會發生這個事件
這個動作差異性稍大,大約可以分成三種情形

(1) IE,Chrome,FireFox
(2) Opera
(3) Safari

這次分家分的比較特別了,我們分別討論如下:



(1) IE,Chrome,FireFox


在 IE 裡,如果我們把滑鼠從圖片範圍外面移到圖片範圍內,按下滑鼠左鍵,開始拖曳一段距離,放掉滑鼠,然後把滑鼠移到圖片範圍外

其情形如下圖:



如果把這件動作順序加上括號,則如下所示:


( onMouseMove -> onMouseOver ) -> ( onMouseMove -> ......... -> onMouseMove )

-> ( onMouseDown -> onMouseMove -> ......... -> onMouseMove ) -> ( onDragStart ) -> ( onDragEnd )

-> ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )

(a)第一個括號: ( onMouseMove -> onMouseOver )

代表把滑鼠從圖片範圍外移到圖片範圍內,
如前所述,IE 會先有一個 onMouseMove,然後才有 onMouseOver
FireFox及 Chrome則只有一個 onMouseOver


(b)第二個括號: ( onMouseMove -> ......... -> onMouseMove )

代表在圖片範圍內移動

(c)第三個括號:( onMouseDown -> onMouseMove -> ......... -> onMouseMove )

代表按下滑鼠,還沒拖曳前,會先有一個 onMouseDown,然後是一堆的 onMouseMove

到底會有幾個 onMouseMove 則跟你在按下滑鼠後,多快開始拖曳有關

若按下滑鼠後,很多的開始拖曳,則後面跟著的 onMouseMove 會比較少

若按下滑鼠後,比較慢的開始拖曳,則後面跟著的 onMouseMove 會比較多

我的測試是,不管多快,IE 跟 Chrome 一定會有 onMouseMove

但是如果夠快的話 FireFox後面可能會沒有 onMouseMove

這可能跟前面提到的 IE 跟 Chrome 對 onMouseMove 比較敏感有關


(d)第四個和第五圖括號: ( onDragStart ) -> ( onDragEnd )

則代表開始拖曳,移動一段距離,到拖曳結束(放開滑鼠)

開始拖曳時,會出現 onDragStart

移動一段距離時,則不會有 onMouseMove 等其他事件發生

拖曳結束,放開滑鼠時,則會出現 onDragEnd 事件

(e)第六個和第七個括號: ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )

則代表把滑鼠移到圖片範圍外面




(2) Opera



( onMouseOver ) -> ( onMouseMove -> ......... -> onMouseMove )

-> ( onMouseDown -> onMouseMove -> ......... -> onMouseMove ) -> ( onDragStart ) -> ( onDragEnd )

-> ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )


他比IE少了第三個括號

也就是 按下滑鼠左鍵,開始拖曳這整個過程,他只有 onDragStart一個事件

不會像 IE 先有 onMouseDow,再 onMouseMove,然後才 onDragStart

(3)Safari





( onMouseOver ) -> ( onMouseMove -> ......... -> onMouseMove )

-> ( onMouseDown -> onMouseMove -> ......... -> onMouseMove ) ->

( onDragStart ) -> ( onMouseMove ) --> ( onDragEnd )

-> ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )

他跟 IE 比有兩個地方不同,跟 opera比則有一個地方不同,討論如下:

(1)他和 oepra一樣,比 IE 少了第三個括號

也就是 按下滑鼠左鍵,開始拖曳這整個過程,他只有 onDragStart一個事件

不會像 IE 先有 onMouseDow,再 onMouseMove,然後才 onDragStart


(2) 另外,他在 onDragStart 開始後,會有一個 onMouseMove,而且一定只有一個,似乎代表拖曳移動的過程



(3)另外,比較特的是,safara有時候會不小心出現兩次 onDragStart --> onMouseMove 如下所示



程式內容如下(請自動忽略& nbsp):

</html> <head> <script language=javascript> var msg=""; function myUp() { if( document.getElementById("up").checked) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { msg+="onMouseUp發生<br>"; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } } function myDown() { if( document.getElementById("down").checked) { msg+="onMouseDown發生<br>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} } function myClick() { if( document.getElementById("click").checked) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { msg+="onClick發生<BR>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} } function myDblClick() { if( document.getElementById("dblclick").checked) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { msg+="onDblClick發生<BR>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} } function myOver() { if( document.getElementById("over").checked) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { msg+="onMouseOver發生<br>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } function myMove() { if( document.getElementById("move").checked) { msg+="onMouseMove發生<br>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } function myOut() { if( document.getElementById("out").checked) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { msg+="onMouseOut發生<br>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } function myDragStart() { if( document.getElementById("dragstart").checked) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { msg+="onDragStart發生<BR>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} } function myDragEnd() { if( document.getElementById("dragend").checked) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { msg+="onDragEnd發生<BR>" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; document.getElementById("dv").innerHTML= msg &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} } </script> </head> <body> <table> <tr> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <td width = 200 valign=top> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <div id=dv ></div> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </td> <td valign=top> <img src="img-1.jpg" onMouseUp = "myUp()" onMouseDown="myDown()" onClick="myClick()" onDblClick="myDblClick()" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; onMouseOver="myOver()" onMouseMove="myMove()" onMouseOut="myOut()" onDragStart="myDragStart()" onDragEnd="myDragEnd()"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;> </td> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <td valign=top > <form> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本程式事件觸發的對像為左側的圖片<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 請勾選想要測試的事件:<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =down > onMouseDown <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =up > onMouseUp <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =click > onClick <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =dblclick > onDblClick <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =over > onMouseOver <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =move > onMouseMove <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =out > onMouseOut <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =dragstart > onDragStart <br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type=checkbox id =dragend > onDragEnd <br> <input type=button value=清空訊息 onClick="msg='';document.getElementById('dv').innerHTML= msg"/> </form> </td> </tr> </talbe> </body> <html>












動作 以滑鼠按一下中間的圖片
事件順序 IE9
FireFox
Chrome
Opera
Safari

onMouseDown --> onMouseUp --> onClick














動作 滑鼠在圖片上連按二下
事件順序 FireFox
Chrome
Opera
Safari

( onMouseDown --> onMouseUp --> onClick ) --> ( onMouseDown --> onMouseUp --> onClick ) --> onDblClick
IE9 ( onMouseDown --> onMouseUp --> onClick ) --> onMouseUp --> onDblClick














動作 把滑鼠從圖片外面移動進圖片範圍,再移動出來
事件順序 FireFox
Chrome
Opera
Safari

( onMouseOver ) --> ( onMouseMove -> onMouseMove -> ........ -> onMouseMove ) -> ( onMouseOut )
IE9 ( onMouseMouse --> onMouseOver ) --> ( onMouseMove -> onMouseMove -> ........ -> onMouseMove ) -> ( onMouseOut )






















動作 把滑鼠從圖片範圍外面移到圖片範圍內,按下滑鼠左鍵,開始拖曳一段距離,放掉滑鼠,然後把滑鼠移到圖片範圍外
事件順序 IE
( onMouseMove -> onMouseOver ) -> ( onMouseMove -> ......... -> onMouseMove )
-> ( onMouseDown -> onMouseMove -> ......... -> onMouseMove ) -> ( onDragStart ) -> ( onDragEnd )
-> ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )
FireFox
Chrome

( onMouseOver ) -> ( onMouseMove -> ......... -> onMouseMove )
-> ( onMouseDown -> onMouseMove -> ......... -> onMouseMove ) -> ( onDragStart ) -> ( onDragEnd )
-> ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )
Opera ( onMouseMove -> onMouseOver ) -> ( onMouseMove -> ......... -> onMouseMove )
-> ( onMouseDown -> onMouseMove -> ......... -> onMouseMove ) -> ( onDragStart ) -> ( onDragEnd )
-> ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )
Safari ( onMouseOver ) -> ( onMouseMove -> ......... -> onMouseMove )
-> ( onMouseDown -> onMouseMove -> ......... -> onMouseMove ) ->
( onDragStart ) -> ( onMouseMove ) --> ( onDragEnd )
-> ( onMouseMove -> ......... -> onMouseMove ) --> ( onMouseOut )




Edited 9 time(s). Last edit at 08/22/2012 10:52PM by RandomVariable.
(編輯記錄)