鼠標事件的種類
鼠標事件主要有下面這些,所有事件都繼承了MouseEvent
接口(詳見后文)。
(1)點擊事件
鼠標點擊相關的有四個事件。
click
:按下鼠標(通常是按下主按鈕)時觸發(fā)。dblclick
:在同一個元素上雙擊鼠標時觸發(fā)。mousedown
:按下鼠標鍵時觸發(fā)。mouseup
:釋放按下的鼠標鍵時觸發(fā)。
click
事件可以看成是兩個事件組成的:用戶在同一個位置先觸發(fā)mousedown
,再觸發(fā)mouseup
。因此,觸發(fā)順序是,mousedown
首先觸發(fā),mouseup
接著觸發(fā),click
最后觸發(fā)。
雙擊時,dblclick
事件則會在mousedown
、mouseup
、click
之后觸發(fā)。
(2)移動事件
鼠標移動相關的有五個事件。
mousemove
:當鼠標在一個節(jié)點內部移動時觸發(fā)。當鼠標持續(xù)移動時,該事件會連續(xù)觸發(fā)。為了避免性能問題,建議對該事件的監(jiān)聽函數(shù)做一些限定,比如限定一段時間內只能運行一次。mouseenter
:鼠標進入一個節(jié)點時觸發(fā),進入子節(jié)點不會觸發(fā)這個事件(詳見后文)。mouseover
:鼠標進入一個節(jié)點時觸發(fā),進入子節(jié)點會再一次觸發(fā)這個事件(詳見后文)。mouseout
:鼠標離開一個節(jié)點時觸發(fā),離開父節(jié)點也會觸發(fā)這個事件(詳見后文)。mouseleave
:鼠標離開一個節(jié)點時觸發(fā),離開父節(jié)點不會觸發(fā)這個事件(詳見后文)。
mouseover
事件和mouseenter
事件,都是鼠標進入一個節(jié)點時觸發(fā)。兩者的區(qū)別是,mouseenter
事件只觸發(fā)一次,而只要鼠標在節(jié)點內部移動,mouseover
事件會在子節(jié)點上觸發(fā)多次。
/* HTML 代碼如下
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
*/
var ul = document.querySelector('ul');
// 進入 ul 節(jié)點以后,mouseenter 事件只會觸發(fā)一次
// 以后只要鼠標在節(jié)點內移動,都不會再觸發(fā)這個事件
// event.target 是 ul 節(jié)點
ul.addEventListener('mouseenter', function (event) {
event.target.style.color = 'purple';
setTimeout(function () {
event.target.style.color = '';
}, 500);
}, false);
// 進入 ul 節(jié)點以后,只要在子節(jié)點上移動,mouseover 事件會觸發(fā)多次
// event.target 是 li 節(jié)點
ul.addEventListener('mouseover', function (event) {
event.target.style.color = 'orange';
setTimeout(function () {
event.target.style.color = '';
}, 500);
}, false);
上面代碼中,在父節(jié)點內部進入子節(jié)點,不會觸發(fā)mouseenter
事件,但是會觸發(fā)mouseover
事件。
mouseout
事件和mouseleave
事件,都是鼠標離開一個節(jié)點時觸發(fā)。兩者的區(qū)別是,在父元素內部離開一個子元素時,mouseleave
事件不會觸發(fā),而mouseout
事件會觸發(fā)。
/* HTML 代碼如下
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
*/
var ul = document.querySelector('ul');
// 先進入 ul 節(jié)點,然后在節(jié)點內部移動,不會觸發(fā) mouseleave 事件
// 只有離開 ul 節(jié)點時,觸發(fā)一次 mouseleave
// event.target 是 ul 節(jié)點
ul.addEventListener('mouseleave', function (event) {
event.target.style.color = 'purple';
setTimeout(function () {
event.target.style.color = '';
}, 500);
}, false);
// 先進入 ul 節(jié)點,然后在節(jié)點內部移動,mouseout 事件會觸發(fā)多次
// event.target 是 li 節(jié)點
ul.addEventListener('mouseout', function (event) {
event.target.style.color = 'orange';
setTimeout(function () {
event.target.style.color = '';
}, 500);
}, false);
上面代碼中,在父節(jié)點內部離開子節(jié)點,不會觸發(fā)mouseleave
事件,但是會觸發(fā)mouseout
事件。
(3)其他事件
contextmenu
:按下鼠標右鍵時(上下文菜單出現(xiàn)前)觸發(fā),或者按下“上下文”菜單鍵時觸發(fā)。wheel
:滾動鼠標的滾輪時觸發(fā),該事件繼承的是WheelEvent
接口。
MouseEvent 接口
MouseEvent
接口代表了鼠標相關的事件,單擊(click)、雙擊(dblclick)、松開鼠標鍵(mouseup)、按下鼠標鍵(mousedown)等動作,所產生的事件對象都是MouseEvent
實例。此外,滾輪事件和拖拉事件也是MouseEvent
實例。
MouseEvent
接口繼承了Event
接口,所以擁有Event
的所有屬性和方法,并且還提供鼠標獨有的屬性和方法。
瀏覽器原生提供一個MouseEvent()
構造函數(shù),用于新建一個MouseEvent
實例。
var event = new MouseEvent(type, options);
MouseEvent()
構造函數(shù)接受兩個參數(shù)。第一個參數(shù)是字符串,表示事件名稱;第二個參數(shù)是一個事件配置對象,該參數(shù)可選。除了Event
接口的實例配置屬性,該對象可以配置以下屬性,所有屬性都是可選的。
screenX
:數(shù)值,鼠標相對于屏幕的水平位置(單位像素),默認值為0,設置該屬性不會移動鼠標。screenY
:數(shù)值,鼠標相對于屏幕的垂直位置(單位像素),其他與screenX
相同。clientX
:數(shù)值,鼠標相對于程序窗口的水平位置(單位像素),默認值為0,設置該屬性不會移動鼠標。clientY
:數(shù)值,鼠標相對于程序窗口的垂直位置(單位像素),其他與clientX
相同。ctrlKey
:布爾值,是否同時按下了 Ctrl 鍵,默認值為false
。shiftKey
:布爾值,是否同時按下了 Shift 鍵,默認值為false
。altKey
:布爾值,是否同時按下 Alt 鍵,默認值為false
。metaKey
:布爾值,是否同時按下 Meta 鍵,默認值為false
。button
:數(shù)值,表示按下了哪一個鼠標按鍵,默認值為0
,表示按下主鍵(通常是鼠標的左鍵)或者當前事件沒有定義這個屬性;1
表示按下輔助鍵(通常是鼠標的中間鍵),2
表示按下次要鍵(通常是鼠標的右鍵)。buttons
:數(shù)值,表示按下了鼠標的哪些鍵,是一個三個比特位的二進制值,默認為0
(沒有按下任何鍵)。1
(二進制001
)表示按下主鍵(通常是左鍵),2
(二進制010
)表示按下次要鍵(通常是右鍵),4
(二進制100
)表示按下輔助鍵(通常是中間鍵)。因此,如果返回3
(二進制011
)就表示同時按下了左鍵和右鍵。relatedTarget
:節(jié)點對象,表示事件的相關節(jié)點,默認為null
。mouseenter
和mouseover
事件時,表示鼠標剛剛離開的那個元素節(jié)點;mouseout
和mouseleave
事件時,表示鼠標正在進入的那個元素節(jié)點。
下面是一個例子。
function simulateClick() {
var event = new MouseEvent('click', {
'bubbles': true,
'cancelable': true
});
var cb = document.getElementById('checkbox');
cb.dispatchEvent(event);
}
上面代碼生成一個鼠標點擊事件,并觸發(fā)該事件。
MouseEvent 接口的實例屬性
MouseEvent.altKey,MouseEvent.ctrlKey,MouseEvent.metaKey,MouseEvent.shiftKey #
MouseEvent.altKey
、MouseEvent.ctrlKey
、MouseEvent.metaKey
、MouseEvent.shiftKey
這四個屬性都返回一個布爾值,表示事件發(fā)生時,是否按下對應的鍵。它們都是只讀屬性。
altKey
屬性:Alt 鍵ctrlKey
屬性:Ctrl 鍵metaKey
屬性:Meta 鍵(Mac 鍵盤是一個四瓣的小花,Windows 鍵盤是 Windows 鍵)shiftKey
屬性:Shift 鍵
// HTML 代碼如下
// <body onclick="showKey(event)">
function showKey(e) {
console.log('ALT key pressed: ' + e.altKey);
console.log('CTRL key pressed: ' + e.ctrlKey);
console.log('META key pressed: ' + e.metaKey);
console.log('SHIFT key pressed: ' + e.shiftKey);
}
上面代碼中,點擊網頁會輸出是否同時按下對應的鍵。
MouseEvent.button,MouseEvent.buttons
MouseEvent.button
屬性返回一個數(shù)值,表示事件發(fā)生時按下了鼠標的哪個鍵。該屬性只讀。
- 0:按下主鍵(通常是左鍵),或者該事件沒有初始化這個屬性(比如
mousemove
事件)。 - 1:按下輔助鍵(通常是中鍵或者滾輪鍵)。
- 2:按下次鍵(通常是右鍵)。
// HTML 代碼為
// <button onmouseup="whichButton(event)">點擊</button>
var whichButton = function (e) {
switch (e.button) {
case 0:
console.log('Left button clicked.');
break;
case 1:
console.log('Middle button clicked.');
break;
case 2:
console.log('Right button clicked.');
break;
default:
console.log('Unexpected code: ' + e.button);
}
}
MouseEvent.buttons
屬性返回一個三個比特位的值,表示同時按下了哪些鍵。它用來處理同時按下多個鼠標鍵的情況。該屬性只讀。
- 1:二進制為
001
(十進制的1),表示按下左鍵。 - 2:二進制為
010
(十進制的2),表示按下右鍵。 - 4:二進制為
100
(十進制的4),表示按下中鍵或滾輪鍵。
同時按下多個鍵的時候,每個按下的鍵對應的比特位都會有值。比如,同時按下左鍵和右鍵,會返回3(二進制為011)。
MouseEvent.clientX,MouseEvent.clientY
MouseEvent.clientX
屬性返回鼠標位置相對于瀏覽器窗口左上角的水平坐標(單位像素),MouseEvent.clientY
屬性返回垂直坐標。這兩個屬性都是只讀屬性。
// HTML 代碼為
// <body onmousedown="showCoords(event)">
function showCoords(evt){
console.log(
'clientX value: ' + evt.clientX + '\n' +
'clientY value: ' + evt.clientY + '\n'
);
}
這兩個屬性還分別有一個別名MouseEvent.x
和MouseEvent.y
。
MouseEvent.movementX,MouseEvent.movementY
MouseEvent.movementX
屬性返回當前位置與上一個mousemove
事件之間的水平距離(單位像素)。數(shù)值上,它等于下面的計算公式。
currentEvent.movementX = currentEvent.screenX - previousEvent.screenX
MouseEvent.movementY
屬性返回當前位置與上一個mousemove
事件之間的垂直距離(單位像素)。數(shù)值上,它等于下面的計算公式。
currentEvent.movementY = currentEvent.screenY - previousEvent.screenY。
這兩個屬性都是只讀屬性。
MouseEvent.screenX,MouseEvent.screenY
MouseEvent.screenX
屬性返回鼠標位置相對于屏幕左上角的水平坐標(單位像素),MouseEvent.screenY
屬性返回垂直坐標。這兩個屬性都是只讀屬性。
// HTML 代碼如下
// <body onmousedown="showCoords(event)">
function showCoords(evt) {
console.log(
'screenX value: ' + evt.screenX + '\n',
'screenY value: ' + evt.screenY + '\n'
);
}
MouseEvent.offsetX,MouseEvent.offsetY
MouseEvent.offsetX
屬性返回鼠標位置與目標節(jié)點左側的padding
邊緣的水平距離(單位像素),MouseEvent.offsetY
屬性返回與目標節(jié)點上方的padding
邊緣的垂直距離。這兩個屬性都是只讀屬性。
/* HTML 代碼如下
<style>
p {
width: 100px;
height: 100px;
padding: 100px;
}
</style>
<p>Hello</p>
*/
var p = document.querySelector('p');
p.addEventListener(
'click',
function (e) {
console.log(e.offsetX);
console.log(e.offsetY);
},
false
);
上面代碼中,鼠標如果在p
元素的中心位置點擊,會返回150 150
。因此中心位置距離左側和上方的padding
邊緣,等于padding
的寬度(100像素)加上元素內容區(qū)域一半的寬度(50像素)。
MouseEvent.pageX,MouseEvent.pageY
MouseEvent.pageX
屬性返回鼠標位置與文檔左側邊緣的距離(單位像素),MouseEvent.pageY
屬性返回與文檔上側邊緣的距離(單位像素)。它們的返回值都包括文檔不可見的部分。這兩個屬性都是只讀。
/* HTML 代碼如下
<style>
body {
height: 2000px;
}
</style>
*/
document.body.addEventListener(
'click',
function (e) {
console.log(e.pageX);
console.log(e.pageY);
},
false
);
上面代碼中,頁面高度為2000像素,會產生垂直滾動條。滾動到頁面底部,點擊鼠標輸出的pageY
值會接近2000。
MouseEvent.relatedTarget
MouseEvent.relatedTarget
屬性返回事件的相關節(jié)點。對于那些沒有相關節(jié)點的事件,該屬性返回null
。該屬性只讀。
下表列出不同事件的target
屬性值和relatedTarget
屬性值義。
事件名稱 | target 屬性 | relatedTarget 屬性 |
---|---|---|
focusin | 接受焦點的節(jié)點 | 喪失焦點的節(jié)點 |
focusout | 喪失焦點的節(jié)點 | 接受焦點的節(jié)點 |
mouseenter | 將要進入的節(jié)點 | 將要離開的節(jié)點 |
mouseleave | 將要離開的節(jié)點 | 將要進入的節(jié)點 |
mouseout | 將要離開的節(jié)點 | 將要進入的節(jié)點 |
mouseover | 將要進入的節(jié)點 | 將要離開的節(jié)點 |
dragenter | 將要進入的節(jié)點 | 將要離開的節(jié)點 |
dragexit | 將要離開的節(jié)點 | 將要進入的節(jié)點 |
下面是一個例子。
/*
HTML 代碼如下
<div id="outer" style="height:50px;width:50px;border:1px solid black;">
<div id="inner" style="height:25px;width:25px;border:1px solid black;"></div>
</div>
*/
var inner = document.getElementById('inner');
inner.addEventListener('mouseover', function (event) {
console.log('進入' + event.target.id + ' 離開' + event.relatedTarget.id);
}, false);
inner.addEventListener('mouseenter', function (event) {
console.log('進入' + event.target.id + ' 離開' + event.relatedTarget.id);
});
inner.addEventListener('mouseout', function (event) {
console.log('離開' + event.target.id + ' 進入' + event.relatedTarget.id);
});
inner.addEventListener("mouseleave", function (event){
console.log('離開' + event.target.id + ' 進入' + event.relatedTarget.id);
});
// 鼠標從 outer 進入inner,輸出
// 進入inner 離開outer
// 進入inner 離開outer
// 鼠標從 inner進入 outer,輸出
// 離開inner 進入outer
// 離開inner 進入outer
MouseEvent 接口的實例方法
MouseEvent.getModifierState()
MouseEvent.getModifierState
方法返回一個布爾值,表示有沒有按下特定的功能鍵。它的參數(shù)是一個表示功能鍵的字符串。
document.addEventListener('click', function (e) {
console.log(e.getModifierState('CapsLock'));
}, false);
上面的代碼可以了解用戶是否按下了大寫鍵。
WheelEvent 接口
概述
WheelEvent 接口繼承了 MouseEvent 實例,代表鼠標滾輪事件的實例對象。目前,鼠標滾輪相關的事件只有一個wheel
事件,用戶滾動鼠標的滾輪,就生成這個事件的實例。
瀏覽器原生提供WheelEvent()
構造函數(shù),用來生成WheelEvent
實例。
var wheelEvent = new WheelEvent(type, options);
WheelEvent()
構造函數(shù)可以接受兩個參數(shù),第一個是字符串,表示事件類型,對于滾輪事件來說,這個值目前只能是wheel
。第二個參數(shù)是事件的配置對象。該對象的屬性除了Event
、UIEvent
的配置屬性以外,還可以接受以下幾個屬性,所有屬性都是可選的。
deltaX
:數(shù)值,表示滾輪的水平滾動量,默認值是 0.0。deltaY
:數(shù)值,表示滾輪的垂直滾動量,默認值是 0.0。deltaZ
:數(shù)值,表示滾輪的 Z 軸滾動量,默認值是 0.0。deltaMode
:數(shù)值,表示相關的滾動事件的單位,適用于上面三個屬性。0
表示滾動單位為像素,1
表示單位為行,2
表示單位為頁,默認為0
。
實例屬性
WheelEvent
事件實例除了具有Event
和MouseEvent
的實例屬性和實例方法,還有一些自己的實例屬性,但是沒有自己的實例方法。
下面的屬性都是只讀屬性。
WheelEvent.deltaX
:數(shù)值,表示滾輪的水平滾動量。WheelEvent.deltaY
:數(shù)值,表示滾輪的垂直滾動量。WheelEvent.deltaZ
:數(shù)值,表示滾輪的 Z 軸滾動量。WheelEvent.deltaMode
:數(shù)值,表示上面三個屬性的單位,0
是像素,1
是行,2
是頁。
更多建議: