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級”鼠標事件:
1 var isSupported = document.implementation.hasFeature("MouseEvents", "2.0");
2 alert(isSupported); //true
是否支持“DOM3級”鼠標事件:
1 var isSupported = document.implementation.hasFeature("MouseEvent", "3.0");
2 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);
4 });
在頁面沒有滾動的情況下,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;
}
}