前言:這是筆者學習之後自己的理解與整理。如果有錯誤或者疑問的地方,請大家指正,我會持續更新! 滑鼠事件 滑鼠事件共10類,包括click、contextmenu(右鍵)、dblclick(雙擊)、mousedown、mouseup、mousemove、mouseover、mouseout、mouse ...
前言:這是筆者學習之後自己的理解與整理。如果有錯誤或者疑問的地方,請大家指正,我會持續更新!
滑鼠事件
滑鼠事件共10類,包括click、contextmenu(右鍵)、dblclick(雙擊)、mousedown、mouseup、mousemove、mouseover、mouseout、mouseenter和mouseleave;
頁面上的所有元素都支持滑鼠事件,除了 mouseenter 和 mouseleave 事件外,所有的滑鼠事件都會冒泡;safari 瀏覽器不支持 mouseenter 和 mouseleave 事件;
順序
- 滑鼠移入某元素時,IE瀏覽器會先觸發一次 mousemove 事件,再觸發 mouseover 和 mouseenter 事件,再觸發多次 mousemove 事件;而其他瀏覽器都是先觸發 mouseover 和 mouseenter 事件,再觸發多次 mousemove 事件;
- 滑鼠移出某元素時,所有瀏覽器的順序都是 mousemove、 mouseout 和 mouseleave 事件;
- 雙擊滑鼠時,一般地,瀏覽器的順序是(1)mousedown、(2)mouseup、(3)click、(4)mousedown、(5)mouseup、(6)click、(7)dblclick;但 IE8及以下瀏覽器有一個小bug,在雙擊事件中,它會跳過第二個 mousedown 和 click 事件,順序為(1)mousedown、(2)mouseup、(3)click、(4)mouseup、(5)dblclick;
- 點擊滑鼠右鍵時,一般地,瀏覽器的順序是(1)mousedown、(2)mouseup、(3)contextmenu;但 safari 瀏覽器有一個小bug,它不觸發 mouseup 事件,順序為(1)mousedown、(2)contextmenu
滑鼠位置
關於滑鼠坐標位置,事件對象提供了 clientX/Y、x/y、pageX/Y、screenX/Y、offsetX/Y、layerX/Y 這6對信息;
- clientX/Y 表示滑鼠指針在可視區域中的水平和垂直坐標;
- x/y 與 clientX/Y 相同,但有相容問題。firefox 瀏覽器不支持 x/y,且IE7及以下瀏覽器把視口的左上角坐標設置為(2,2),其他瀏覽器則將(0,0)作為起點坐標,所以存在(2,2)的差距;一般不用這個;
- screenX/Y 表示滑鼠指針相對於屏幕的水平和垂直坐標;
- pageX/Y 表示相對於頁面的水平和垂直坐標,它與 clientX/clientY 的區別是不隨滾動條的位置變化;
- layerX/Y 與 pageX/Y 相同;IE8及以下瀏覽器不支持 pageX/Y 和 layerX/Y,不過可以根據 scrollTop/Left 和 clientX/Y 計算出來;event.pageX = event.clientX + document.documentElement.scrollLeft;
- offsetX/Y 表示相對於定位父級的水平和垂直坐標;當頁面無定位元素時,body 是元素的定位父級。由於 body 的預設margin是8px,所以 offsetX/Y 與 clientX/Y 差(8,8);
鍵位滑鼠組合
雖然滑鼠事件主要是使用滑鼠來觸發的,但在按下滑鼠時鍵盤上的某些鍵的狀態也可以影響到所要採取的操作
這些修改鍵就是Shift、Ctrl、Alt和Meta(在Windows鍵盤中是Windows鍵,在蘋果機中是Cmd鍵),它們經常被用來修改滑鼠事件的行為
DOM為此規定了4個屬性,表示這些修改鍵的狀態:shiftKey、ctrlKey、altKey 和 metaKey。這些屬性中包含的都是布爾值,如果相應的鍵被按下了,則值為true;否則值為false;IE8及以下瀏覽器不支持 metaKey 屬性;
相關元素
target 屬性返回事件的目標節點;relatedTarget 屬性返回事件的次要相關節點。對於那些沒有次要相關節點的事件,該屬性返回null;
對 mouseover 事件而言,事件的主目標 target 是獲得游標的元素,而相關元素 relatedTarget 就是那個失去游標的元素;
IE8及以下瀏覽器不支持 target 和 relatedTarget 屬性,target 可以用 srcElement 屬性相容,relatedTarget 可以用 toElement 屬性相容;
滑鼠按鍵
button 和 buttons 屬性返回事件滑鼠按鍵信息;
button 屬性返回一個數值,表示按下了滑鼠哪個鍵:
- -1 表示沒有按下按鍵
- 0 表示按下左鍵
- 1 表示按下滾輪
- 2 表示按下右鍵
buttons 屬性返回一個3個比特位的值,表示同時按下了哪些鍵。它用來處理同時按下多個滑鼠鍵的情況;safari 瀏覽器不支持buttons屬性;
- 001 按下滑鼠左鍵
- 010 按下滑鼠右鍵
- 100 按下滾輪
所以,同時按下左鍵和右鍵,buttons的二進位為011,表示3;同時按下左鍵和滾輪,buttons的二進位為101,表示5;同時按下右鍵和滾輪,buttons的二進位為110,表示6。
滾輪事件
滾輪事件與滾動事件不同,滾動事件必須有滾動條,才可以實現。而滾動事件是滾動滑鼠滾輪觸發的事件,與是否有滾動條無關;
IE6首先實現了滑鼠滾輪 mousewheel 事件,當用戶通過滾動與頁面交互、在垂直方向上滾動頁面時,會觸發 mousewheel 事件。最終會冒泡到 document(IE8-)或window(標準);
firefox 瀏覽器不支持 mousewheel 事件,它支持 DOMMouseScroll 事件(該事件僅支持DOM2級事件處理程式的寫法),而有關滑鼠滾輪的信息則保存在 detail 屬性中。當向前滾動滑鼠滾輪時,這個屬性的值是 -3 的倍數;當向後滾動滑鼠滾輪時,這個屬性的值是 3 的倍數。
滾輪事件中有一個 wheelDelta 屬性,當用戶向前滾動滑鼠滾輪時,wheelDelta 是120的倍數;當用戶向後滾動滑鼠滾輪時,wheelDelta 是 -120 的倍數;
<script> var scrollFunc = function (e) { var direct = 0; e = e || window.event; //滾輪事件中有一個 wheelDelta 屬性,當用戶向前滾動滑鼠滾輪時,wheelDelta 是120的倍數;當用戶向後滾動滑鼠滾輪時,wheelDelta 是 -120 的倍數; //firefox 瀏覽器有關滑鼠滾輪的信息則保存在 detail 屬性中。當向前滾動滑鼠滾輪時,這個屬性的值是 -3 的倍數;當向後滾動滑鼠滾輪時,這個屬性的值是 3 的倍數。 if (e.wheelDelta > 0 || e.detail< 0) { console.log("滑輪向上滾動"); } if (e.wheelDelta < 0 || e.detail> 0) { console.log("滑輪向下滾動"); } } //firefox 瀏覽器不支持 mousewheel 事件,它支持 DOMMouseScroll 事件(該事件僅支持DOM2級事件處理程式的寫法) if (document.addEventListener) { document.addEventListener('DOMMouseScroll', scrollFunc, false); } //滾動滑輪觸發scrollFunc方法 window.onmousewheel = document.onmousewheel = scrollFunc; </script>
移動端事件
由於移動設備沒有滑鼠,所以與電腦端有一些不同之處。移動設備儘量使用移動端事件,而不要使用滑鼠事件;
- 不支持 dblclick 雙擊事件。在移動設備中雙擊瀏覽器視窗會放大畫面;
- 單擊元素會觸發 mousemove 事件;
- 兩個手指放在屏幕上且頁面隨手指移動而滾動時會觸發 mousewheel 和 scroll 事件;
鍵盤事件
鍵盤事件用來描述鍵盤行為,主要有 keydown、keypress、keyup 三個事件;
鍵盤事件必須綁定在可以獲得焦點的元素上。而頁面剛載入完成時,焦點處於document元素;
當用戶按下鍵盤上的任意鍵時觸發 keydown,如果按住不放的話,會重覆觸發該事件;
當用戶按下鍵盤上的字元鍵時觸發 keypress,按下功能鍵時不觸發。如果按住不放的話,會重覆觸發該事件;
關於 esc 鍵,各瀏覽器處理不一致。IE瀏覽器和 firefox 瀏覽器按下 esc 鍵時,會觸發 keypress 事件;而 chrome/safari/opera 這三個 webkit 內核的瀏覽器則不會觸發;
IE瀏覽器不完全支持綁定在 document 元素上的 keypress 事件,只有 IE9及以上瀏覽器在使用DOM2級事件處理程式時才支持;
當用戶釋放鍵盤上的鍵時觸發 keyup 事件;
系統為了防止按鍵誤被連續按下,所以在第一次觸發 keydown 事件後,有500ms的延遲,才會觸發第二次 keydown 事件;類似的,keypress 事件也存在500ms的時間間隔;
如果按鍵按下後一直不鬆開,就會連續觸發鍵盤事件,觸發的順序如下:keydown---keypress---keydown---keypress---重覆這一過程---keyup;
按鍵信息
鍵盤事件包括 keyCode、key、char、keyIdentifier 和修改鍵共5個按鍵信息;
在發生鍵盤事件時,event 事件對象的鍵碼 keyCode 屬性中會包含一個代碼,與鍵盤上一個特定的鍵對應。對數字字母字元鍵,keyCode 屬性的值與 ASCII 碼中對應大寫字母或數字的編碼相同;
firfox 瀏覽器不支持 keypress 事件中的 keyCode 屬性;但是我們可以用 event.which 代替;
keyCode 屬性無法區分大小寫字母;
<input id="btn" type="text"> <script type="text/javascript"> btn.onkeydown = function(e){ e = e || event; var x = e.which || e.keyCode; if (x == 13) { alert ("你按下了 enter 鍵!"); } }; </script>
key 屬性是為了取代 keyCode 而新增的,它的值是一個字元串。在按下某個字元鍵時,key 的值就是相應的文本字元;在按下非字元鍵時,key 的值是相應鍵的名,預設為空字元串;IE8及以下瀏覽器不支持,而 safari 瀏覽器不支持 keypress 事件中的 key 屬性;
key 可以區分大小寫;
<input id="btn" type="text"> <script type="text/javascript"> btn.onkeydown = function(e){ e = e || event; var x = e.key; if (x == 'Enter') { alert ("你按下了 enter 鍵!"); } }; </script>
char 屬性在按下字元鍵時的行為與 key 相同,但在按下非字元鍵時值為null ;該屬性只有IE9及以上瀏覽器支持;
keyIdentifier 屬性在按下非字元鍵的情況下與 key 的值相同。對於字元鍵,keyIdentifier 返回一個格式類似 "U+0000" 的字元串,表示 Unicode 值;該屬性只有chrome/safari/opera瀏覽器支持 ;
修改鍵在滑鼠事件中介紹過,在鍵盤事件中也存在修改鍵;
修改鍵就是 Shift、Ctrl、Alt和Meta(在Windows鍵盤中是Windows鍵,在蘋果機中是Cmd鍵)。DOM為此規定了4個屬性,表示這些修改鍵的狀態:shiftKey、ctrlKey、altKey和metaKey。這些屬性中包含的都是布爾值,如果相應的鍵被按下了,則值為true;否則值為false;
提示大寫
大寫有兩種實現方式:一種是在capslock開啟的情況下,另一種是輸入字元時,同時按下shift鍵;
<input id="test"> <span id="tips"></span> <script> var oTest = document.getElementById('test'); var oTips = document.getElementById('tips'); oTest.onkeydown = function(e){ e = e || event; var lShiftKey = e.shiftKey; //通過定時器延遲來獲取當前輸入字元值 setTimeout(function(){ var value = oTest.value.slice(-1); //如果沒有按下shift鍵,並且當前為大寫字母,或者按下shift鍵,且當前為小寫字母 if(!lShiftKey && /[A-Z]/.test(value) || lShiftKey && /[a-z]/.test(value)){ oTips.innerHTML = '當前為大寫模式'; setTimeout(function(){ oTips.innerHTML = ''; },400) } }) } </script>
參考資料
大神的講解更清晰,他的其他隨筆也很好, http://www.cnblogs.com/xiaohuochai/p/5867195.html