14. JS 事件类型

一、鼠标事件

二、键盘事件

一、鼠标事件

(1). 类型

类型 说明
click 当用户按下并释放鼠标按键或其他方式“激活”元素时触发
contextmenu 可以取消的事件,当上下文菜单即将出现时触发。当前浏览器在鼠标右击时显示上下文菜单
dblclick 当用户双击鼠标时触发
mousedown 当用户按下鼠标按键时触发
mouseup 当用户释放鼠标按键时触发
mousemove 当用户移动鼠标时触发
mouseover 当鼠标进入元素时触发。relatedTarget(在IE中是fromElement)指的是鼠标来自的元素
mouseout 当鼠标离开元素时触发。relatedTarget(在IE中是toElement)指的是鼠标要去往的元素
mouseenter 类似mouseover,但不冒泡。IE将其引入,HTML5将其标准化,但尚未广泛实现
mouseleave 类似mouseout,但不冒泡。IE将其引入,HTML5将其标准化,但尚未广泛实现

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

注意:safari浏览器不支持mouseenter和mouseleave事件

(2). 顺序

//一次click = mousedown + mouseup
document.onclick = function() {
    console.log('onclick');
    }
document.onmousedown = function() {
    console.log('mousedown');
}
document.onmouseup = function() {
    console.log('mouseup');
}
// mousedown
// mouseup
// onclick

(3). 属性

1. 坐标位置:clientX/YpageX/YscreenX/Yx/yoffsetX/YlayerX/Y

  • clientX/Yx/y

    • clientX/Y表示鼠标指针在可视区域中的水平和垂直坐标

    • x/yclientX/Y相同,但有兼容问题。firefox浏览器不支持x/y,且IE7-浏览器把视口的左上角坐标设置为(2,2),其他浏览器则将(0,0)作为起点坐标,所以存在(2,2)的差距

// <div id="box" style="height:100px;width:200px;background:pink;"></div>

box.onmousemove=function(e){
    e = e || event;
    box.innerHTML = 'clientX:' + e.clientX +';clientY:'+e.clientY + '<br>x:' + e.x + ';y:' + e.y;
}

  • screenX/Y

    • 表示鼠标指针相对于屏幕的水平和垂直坐标
  • pageX/YlayerX/Y

    • pageX/Y表示相对于页面的水平和垂直坐标,它与clientX/clientY的区别是不随滚动条的位置变化

    • layerX/YpageX/Y相同

    • 注意:IE8-浏览器不支持pageX/Y和layerX/Y,不过可以根据scrollTop/Left和clientX/Y计算出来

封装兼容函数:

handler = function(e){
    e = e || event;
    if(e.pageX == undefined){
        e.pageX = e.clientX + document.documentElement.scrollLeft
    }
    if(e.pageY == undefined){
        e.pageY = e.clientY + document.documentElement.scrollTop 
    }
}
  • offsetX/Y

    • 表示相对于定位父级的水平和垂直坐标

    • 当页面无定位元素时,body是元素的定位父级。由于body的默认margin是8px,所以offsetX/YclientX/Y差(8,8)

2. 修改键:shiftKeyctrlKeyaltKeymetaKey

  • 这些属性中包含的都是布尔值,如果相应的键被按下了,则值为true;否则值为false

  • 注意:IE8-浏览器不支持metaKey属性

3. 鼠标按键:buttonbuttons

  • 返回事件鼠标按键信息

  • button:返回一个数值,表示按下了鼠标哪个键

    • 注意:若不阻止右键默认行为,safari浏览器无法表示按下右键
返回数值 动作
-1 表示没有按下按键
0 表示按下左键
1 表示按下滚轮
2 表示按下右键
  • buttons:返回一个3个比特位的值,表示同时按下了哪些键,它用来处理同时按下多个鼠标键的情况。

    • 注意:safari浏览器不支持buttons属性

    • 同时按下左键和右键,buttons的二进制为011,表示3;

    • 同时按下左键和滚轮,buttons的二进制为101,表示5;

    • 同时按下右键和滚轮,buttons的二进制为110,表示6

数值 表示
1 二进制为001,表示按下左键
2 二进制为010,表示按下右键
4 二进制为100,表示按下滚轮

但,IE8-浏览器的button属性的值与标准的button属性有很大差异

数值 动作
0 表示没有按下按钮
1 表示按下了左键
2 表示按下了右键
3 表示同时按下了左、右键
4 表示按下了滚轮
5 表示同时按下了左键和滚轮
6 表示同时按下了右键和滚轮
7 表示同时按下了左键、右键和滚轮

兼容

  • 可以通过hasFeature()方法来检测

  • hasFeature()方法接受两个参数:要检测的DOM功能的名称及版本号。如果浏览器支持给定名称和版本的功能,则该方法返回true。

var hasMouse = document.implementation.hasFeature('MouseEvents','2.0');
//IE8-浏览器返回false,其他浏览器true
console.log(hasMouse);

4. 滚轮事件:

  • 滚轮事件与滚动事件不同,滚动事件必须有滚动条,才可以实现。而滚轮事件是滚动鼠标滚轮触发的事件,与是否有滚动条无关。

  • 当用户通过滚动与页面交互、在垂直方向上滚动页面时,会触发mousewheel事件。最终会冒泡到document(IE8-)或window(标准)

  • 滚轮事件中有一个 wheelDelta 属性,当用户向前滚动鼠标滚轮时,wheelDelta 是120的倍数;当用户向后滚动鼠标滚轮时,wheelDelta是-120的倍数。

// <div id="box" style="height:100px;width:200px;background:pink;"></div>

box.onmousewheel=function(e){
    e = e || event;
    box.innerHTML = e.wheelDelta;
    if(e.wheelDelta >0){
        box.style.backgroundColor = 'lightblue';
    }else{
        box.style.backgroundColor = 'lightgreen';
    }
}
  • firefox浏览器不支持mousewheel事件,它支持DOMMouseScroll事件,而有关鼠标滚轮的信息则保存在detail属性中,当向前滚动鼠标滚轮时,这个属性的值是-3的倍数,当向后滚动鼠标滚轮时,这个属性的值是3的倍数

    • 注意:该事件仅支持DOM2级事件处理程序的写法

滚轮事件兼容函数:

var handler = function(e){
    var getWheelDelta;
    e = e || event;
    if(e.wheelDelta){
        getWheelDelta = e.wheelDelta;
    }else{
        getWheelDelta = -e.detail * 40;
    }
}

实例:fireFox 与其它浏览器滚轮事件

// <body style="height:2000px">
// <p style="position: fixed">滚动滚轮将显示滚动值</p>
// <div id="test" style="position: fixed"></div>

var wheel = function(e){
    e = e || event;
    if(e.wheelDelta){
        test.innerHTML = e.wheelDelta;
    }else{
        test.innerHTML = -e.detail * 40;
    }
}
document.body.onmousewheel = wheel;
document.body.addEventListener('DOMMouseScroll',wheel,false); 

二、键盘事件

键盘事件由用户击打键盘触发,主要有keydownkeypresskeyup三个事件,它们都继承了KeyboardEvent接口。

  • keydown:当用户按下键盘上的任意键时触发,如果按住不放的话,会重复触发该事件。

  • keypress:按下有值的键(字符键)时触发,即按下 Ctrl、Alt、Shift、Meta 这样无值的键,这个事件不会触发。对于有值的键,按下时先触发keydown事件,再触发这个事件。

  • keyup:松开键盘时触发该事件。

如果用户一直按键不松开,就会连续触发键盘事件,触发的顺序如下:

顺序 触发事件
1 keydown
2 keypress
3 keydown
4 keypress
5 ...(重复以上过程)
6 keyup

[注意]:关于esc键,各浏览器处理不一致。IE浏览器和firefox浏览器按下esc键时,会触发keypress事件;而chrome/safari/opera这三个webkit内核的浏览器则不会触发

[注意]:IE浏览器不完全支持绑定在document元素上的keypress事件,只有IE9+浏览器在使用DOM2级事件处理程序时才支持

键盘事件必须绑定在可以获得焦点的元素上。而页面刚加载完成时,焦点处于document元素。

实例:只有焦点处于id为'test'的元素上,才会发生keypress事件

// <p>请按下键盘上的任意键</p>
// <button id="test" style="height: 30px;width: 200px;background-color: pink;"></button><br>
// <button id="reset">还原</button>

reset.onclick = function(){history.go();}   // 重置
test.focus();   // 焦点
test.onkeypress = function(e){
    e = e || event; // 兼容
    test.innerHTML += e.type;
}

按键信息:

  • keyCode

    • 在发生键盘事件时,event事件对象的键码keyCode属性中会包含一个代码,与键盘上一个特定的键对应。

    • firfox 浏览器不支持keypress事件中的keyCode属性

    • 常用的四个方向按键,左上右下(顺时针)的键码分别是37、38、39、40

  • key

    • 按下某个字符键时,key的值就是相应的文本字符

    • 按下非字符键时,key的值是相应键的名,默认为空字符串

    • IE8-浏览器不支持,而safari浏览器不支持keypress事件中的key属性

  • char

    • 按下字符键时的行为与key相同,但在按下非字符键时值为null

    • 该属性只有IE9+浏览器支持

  • keyIdentifier

    • 按下非字符键的情况下与key的值相同

    • 对于字符键,keyIdentifier返回一个格式类似“U+0000”的字符串,表示Unicode值

    • 该属性只有chrome/safari/opera浏览器支持

// <div id="test" style="height: 100px;width: 200px;background-color: pink;"></div>
// <button id="reset">还原</button>

reset.onclick = function(){history.go();}
document.onkeyup = function(e){
    test.innerHTML = '';

    e = e || event;
    test.innerHTML += "keyCode:" + e.keyCode + "</br>";
    test.innerHTML += "key:" + e.key + "</br>";
    test.innerHTML += "char:" + e.char + "</br>";
    test.innerHTML += "keyIdentifier:" + e.keyIdentifier+ "</br>";
}
  • 修改键

    • 修改键就是Shift、Ctrl、Alt和Meta(在Windows键盘中是Windows键,在苹果机中是Cmd键)

    • 修改键的状态:shiftKey、ctrlKey、altKey和metaKey

    • 这些属性中包含的都是布尔值,如果相应的键被按下了,则值为true;否则值为false

兼容:

  • 一般地,使用key属性和keyCode属性来实现兼容处理。key属性IE8-浏览器不支持,而keyCode属性无法区分大小写字母
var handler = function(e){
    var CompatibleKey;
    e = e || event;
    //支持key属性
    if(e.key != undefined){
        CompatibleKey = e.key;
    }else{
        //当按键是数字或大写字母时
        if(e.keyCode>47 && e.keyCode<58 || e.keyCode>64 && e.keyCode<91){
            CompatibleKey =String.fromCharCode(e.keyCode);
        }else{
            //当案按键是方向按键时
            switch(e.keyCode){
                case 37:
                    CompatibleKey = 'ArrowLeft';
                    break;
                case 38:
                    CompatibleKey = 'ArrowUp';
                    break;
                case 39:
                    CompatibleKey = 'ArrowRight';
                    break;
                case 40:
                    CompatibleKey = 'ArrowDown';
                    break;
            }
        }    
    }
}

键盘事件应用:

(1). 提示大写

  • 在输入框中输入字符时,如果大写模式开启,提示此时为大写模式。提示大写并不是说当前输出的是大写字母,而是说当前caps lock大写按键被按下

  • [注意]:大写有两种实现方式:一种是在capslock开启的情况下,另一种是输入字符时,同时按下shift键

// <input id="test">
// <span id="tips"></span>

test.onkeydown = function(e){
    e = e || event;
    //兼容IE8-浏览器,因为IE8-浏览器不支持在定时器中传递事件对象e
    var shiftKey = e.shiftKey;
    var keyCode = e.keyCode;
    //通过定时器延迟来获取当前输入字符值
    setTimeout(function(){
        var value = test.value.slice(-1);
        //如果没有按下shift键,并且当前为大写字母,或者按下shift键,且当前为小写字母
        if(!shiftKey && /[A-Z]/.test(value) || shiftKey && /[a-z]/.test(value)){
            tips.innerHTML = '当前为大写模式';
            setTimeout(function(){
                tips.innerHTML = '';
            },400)
        }                
    })
}
posted @ 2019-07-16 14:35  胤小飞  阅读(150)  评论(0)    收藏  举报