DOM3級事件中定義了以下9個鼠標事件:
- click:在用戶單擊主鼠標按鈕或者按下回車鍵時觸發。意味着onclick事件處理程序既可以通過鍵盤也可以i通過鼠標執行。
- dbclick:在用戶雙擊主鼠標按鈕時觸發。(在DOM2中沒有規定,在DOM3中做了規定)
- mousedown:在用戶按下任意鼠標按鈕時觸發。
- mouseenter:在鼠標光標從元素外部首次移動到元素范圍之內時觸發。(在DOM2中沒有規定,在DOM3中做了規定)
- mouseleave:在位於元素上方的鼠標光標移動到元素范圍之外時觸發。(在DOM2中沒有規定,在DOM3中做了規定)
- mousemove:當鼠標指針在元素內部移動時重復的觸發。
- mouseout:在鼠標位於一個元素上方,然后移動到另一個元素時觸發,另一個元素可以位於另一個元素的外部,也可以是這個元素的子元素;不能通過鍵盤觸發。
- mouseover:在鼠標位於一個元素外部,然后將其首次移動到另一個元素邊界之內時觸發;不能通過鍵盤觸發
- mouseup:釋放鼠標按鈕時觸發;不能通過鍵盤觸發。
除了mouseenter、mouseleave、dbclick是“DOM3級事件”新增之外,其它事件都是“DOM2級事件”中定義的。
在一個元素上相繼觸發mousedown和mouseup事件,才會觸發click事件。兩次click事件相繼觸發才會觸發dblclick事件。如果取消 了mousedown或mouseup中的一個,click事件就不會被觸發。直接或間接取消了click事件,dblclick事件就不會被觸發了。
這四個事件的觸發順序如下:
(1)mousedown
(2)mouseup
(3)click
(4)mousedown
(5)mouseup
(6)click
(7)dbclick
可以使用如下代碼檢測瀏覽器是否支持“DOM2級”鼠標事件:
var isSupported = document.implementation.hasFeature("MouseEvents", "2.0"); alert(isSupported); //true
是否支持“DOM3級”鼠標事件:
var isSupported = document.implementation.hasFeature("MouseEvent", "3.0"); alert(isSupported); //true
注意:“DOM3級”鼠標事件的feature名為MouseEvent;而“DOM2級”為MouseEvents。
滾輪事件其實就是一個mousewheel事件。
1、客戶區坐標位置
通過事件對象event的clientX和clientY屬性,可以訪問事件發生時鼠標指針在視窗中的水平和垂直坐標。
EventUtil.addHandler(document, "click", function(event) { event =EventUtil.getEvent(event); alert("鼠標指針客戶區坐標為:水平距離—" + event.clientX + ";" + "垂直距離—" + event.clientY + ""); });
注意:這些值不包括頁面滾動的距離,因此這個位置並不表示鼠標在頁面上的位置。
2、頁面坐標位置
客戶區坐標可以知道鼠標是在視口的什么位置發生的,而通過事件對象event的pageX和pageY屬性,可以訪問事件發生時鼠標指針在頁面中的水平和垂直坐標。
EventUtil.addHandler(document, "click", function(event) { event = EventUtil.getEvent(event); alert("鼠標指針頁面坐標為:水平距離—" + event.pageX + ";" + "垂直距離—" + event.pageY); });
在頁面沒有滾動的情況下,pageX和pageY的值與clientX和clientY的值相等。
IE8及更早版本不支持事件對象上的頁面坐標,不過可以使用客戶區坐標和滾動信息計算出來。需要用到document.body(混雜模式)或者document.documentElement(標准模式)中的scrollLeft和scrollTop屬性。
EventUtil.addHandler(document, "click", function(event) { event = EventUtil.getEvent(event); var pageX = event.pageX; var pageY = event.pageY; if(pageX === undefined) { pageX = event.clientX + (document.body.scrollLeft || document.documentElememt.scrollLeft); }; if(pageY === undefined) { pageY = event.clientY + (document.body.scrollTop || document.documentElememt.scrollTop); }; alert("鼠標指針頁面坐標為:水平距離—" + pageX + ";" + "垂直距離—" + pageY); });
3、屏幕坐標位置
通過事件對象event的screenX和screenY屬性,可以訪問事件發生時鼠標指針在電腦屏幕中的水平和垂直坐標。
event_util.addHandler(document, "click", function(event) { event = event_util.getEvent(event); alert("鼠標指針屏幕坐標為:水平距離—" + event.screenX + ";" + "垂直距離—" + event.screenY); });
4、修改鍵
Shift、Ctrl、Alt、Meta這些修改鍵經常被用來修改鼠標事件的行為,DOM為此規定了4個屬性,表示這些修改鍵的狀態:shiftKey、ctrlKey、altKey、metaKey。這些屬性中包含的都是布爾值,如果值為true,表示相應的鍵被按下,否則為false。當某個鼠標事件發生時,通過檢測這4個屬性,就能確定用戶是否按下某個修改鍵。
var div = document.getElementById("myDiv"); EventUtil.addHandler(div, "click", function(event){ event = EventUtil.getEvent(event); var keys = new Array(); //當屬性值為true時,將對應修改鍵的名稱田間到keys數組中 if (event.shiftKey){ keys.push("shift"); } if (event.ctrlKey){ keys.push("ctrl"); } if (event.altKey){ keys.push("alt"); } if (event.metaKey){ keys.push("meta"); } alert("Keys: " + keys.join(",")); });
5、相關元素
- 對mouseover事件而言,事件的主目標就是獲得光標的元素,而相關元素就是失去光標的那個元素;
- 對mouseout事件而言,事件的主目標就是失去光標的元素,而相關元素就是獲得光標的那個元素。
DOM通過event事件對象的relatedTarget屬性提供了相關元素的信息,這個屬性只對mouseover和mouseout事件才包含值;對於其他事件,其值為null。
IE8及之前版本不支持relatedTarget屬性,但提供相似的屬性。在mouseover事件觸發時,IE的fromElement屬性中保存着相關元素;在mouseout事件觸發時,IE的toElement屬性中保存了相關元素。
IE9支持所有的這些屬性。
將跨瀏覽器取得相關元素的方法getRelatedTarge()添加到EventUtil對象中.
getRelatedTarget: function(event) { if(event.relatedTarget) { return event.relatedTarget; } else if(event.fromElement) { return event.fromElement; } else if(event.toElement) { return event.toElement; } else { return null; } }
6、鼠標按鈕
只有在主鼠標按鈕被單擊(或鍵盤回車鍵被按下)時才會觸發click事件,所以需要檢測按鈕的信息,對於mousedown和mouseup事件而言,在event事件對象中存在一個button屬性,表示按下或釋放的按鈕。
DOM中的button屬性可能有以下三個值:
- 0,表示主鼠標按鈕(鼠標左鍵);
- 1,表示中間按鈕;
- 2,表示次鼠標按鈕(鼠標右鍵)。
IE8及之前版本中,也提供button屬性,但其屬性值與DOM的不太通屬性值有很大差別。
- 0:沒有按下鼠標按鈕;
- 1:主鼠標按鈕;
- 2:次鼠標按鈕;
- 3:同時按下主鼠標按鈕和次鼠標按鈕;
- 4:中間鼠標按鈕;
- 5:同時按下主鼠標按鈕和中間鼠標按鈕;
- 6:同時按下次鼠標按鈕和中間鼠標按鈕;
- 7:同時按下三個鼠標按鈕
EventUtil對象添加getButton()方法。
var EventUtil={ //省略其他代碼 getButton: function(event) { if(document.implementation.hasFeature("MouseEvents", "2.0")) { //確定event對象中存在的button屬性中是否包含正確的值 return event.button; } else { //不包含正確的值,說明是ie,需要對相應的值進行規范化,將IE模型規范化為DOM方式 switch(event.button) { case 0: case 1: case 3: case 5: case 7: return 0; case 2: case 6: return 2; case 4: return 1; } } } //省略其他代碼 }
7、更多的事件信息
對於鼠標事件來說,detail屬性中包含一個數值,表示在給定位置上發生多少次單擊;在同一個位置上相繼發生mousedown和mouseup事件算作一次單擊。detail從1開始計數。如果鼠標在mousedown和mouseup事件之間移動了位置,則detail的值會被重置為0。
8、鼠標滾輪事件
當用戶通過鼠標滾輪與頁面交互、在垂直方向上滾動頁面時,會觸發mousewheel事件,該事件可以在任何元素上觸發,最終會冒泡到document(IE8)或window(IE9、Opera、Chrome和Safari)對象。與mousewheel事件對應的event對象除了包含鼠標事件的所有標准信息之外,還包含一個特殊的wheelDelta屬性;當用戶向前滾動鼠標滾輪時,wheelDelta是120的倍數,當用戶向后滾動鼠標滾輪時,wheelDelta是-120的倍數。
下述代碼可以得到wheelDelta的值,但多數情況下,只需要知道滾動鼠標滾輪的方向,而這通過檢測wheelDelta的正負號就可以確定。
EventUtil.addHandler(document, "mousewheel", function(event) { event = EventUtil.getEvent(event); alert(event.wheelDelta); });
注意:在Opera9.5及之前版本中,wheelDelta的正負號是顛倒的;可以使用瀏覽器檢測技術來確定實際的值,如下:
EventUtil.addHandler(document, "mousewheel", function(event) { event = EventUtil.getEvent(event); var delta = (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta) alert(delta); });
在Firefox瀏覽器中,支持一個名為DOMMouseScroll的事件,也是在鼠標滾輪滾動時觸發,其被視為鼠標事件,包含與鼠標事件有關的所有信息;而有關鼠標滾輪的信息則保存在detail屬性中,當向前滾動滾輪時,其值為-3的倍數,當向后滾動滾輪時,其值為3的倍數。
可以將DOMMouseScroll事件添加到頁面中的任何元素,而且該事件會冒泡到window對象。所以可以像下面這樣針對這個事件來添加事件處理程序:
EventUtil.addHandler(document, "DOMMouseScroll", function(event) { event =EventUtil.getEvent(event); alert(event.detail); });
跨瀏覽器環境下的解決方案:
getWheelDelta: function(event) { if(event.wheelDelta) { return event.wheelDelta; } else { return -event.detail * 40; } }