jacascript 鼠标事件和键盘事件

前言:这是笔者学习之后自己的理解与整理。如果有错误或者疑问的地方,请大家指正,我会持续更新!

鼠标事件

  鼠标事件共10类,包括click、contextmenu(右键)、dblclick(双击)、mousedown、mouseup、mousemove、mouseover、mouseout、mouseenter和mouseleave;

  页面上的所有元素都支持鼠标事件,除了 mouseenter 和 mouseleave 事件外,所有的鼠标事件都会冒泡;safari 浏览器不支持 mouseenter 和 mouseleave 事件

顺序

  1. 鼠标移入某元素时,IE浏览器会先触发一次 mousemove 事件,再触发 mouseover 和 mouseenter 事件,再触发多次 mousemove 事件;而其他浏览器都是先触发 mouseover 和 mouseenter 事件,再触发多次 mousemove 事件;
  2. 鼠标移出某元素时,所有浏览器的顺序都是 mousemove、 mouseout 和 mouseleave 事件;
  3. 双击鼠标时,一般地,浏览器的顺序是(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;
  4. 点击鼠标右键时,一般地,浏览器的顺序是(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对信息;

  1. clientX/Y 表示鼠标指针在可视区域中的水平和垂直坐标;
  2. x/y 与 clientX/Y 相同,但有兼容问题。firefox 浏览器不支持 x/y,且IE7及以下浏览器把视口的左上角坐标设置为(2,2),其他浏览器则将(0,0)作为起点坐标,所以存在(2,2)的差距;一般不用这个
  3. screenX/Y 表示鼠标指针相对于屏幕的水平和垂直坐标;
  4. pageX/Y 表示相对于页面的水平和垂直坐标,它与 clientX/clientY 的区别是不随滚动条的位置变化;
  5. layerX/Y 与 pageX/Y 相同;IE8及以下浏览器不支持 pageX/Y 和 layerX/Y,不过可以根据 scrollTop/Left 和 clientX/Y 计算出来;event.pageX = event.clientX + document.documentElement.scrollLeft;
  6. 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>

移动端事件

  由于移动设备没有鼠标,所以与电脑端有一些不同之处。移动设备尽量使用移动端事件,而不要使用鼠标事件;

  1. 不支持 dblclick 双击事件。在移动设备中双击浏览器窗口会放大画面;
  2. 单击元素会触发 mousemove 事件;
  3. 两个手指放在屏幕上且页面随手指移动而滚动时会触发 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>
原文地址:https://www.cnblogs.com/sspeng/p/6861764.html