天天看点

js中的鼠标和滚轮事件 — 第13.4.3节

JavaScript中的鼠标和滚轮事件

一:鼠标事件分类?

DOM3级鼠标事件分为9种:

1. click:一般是鼠标左键按下或者回车键按下;

2. dbclick:在用户双击鼠标按钮的时候触发(一般左键);

3. mousedown:用户按下了任意鼠标按钮时触发;

4. mouseenter: 在鼠标从元素外部首次移到元素范围之内时触发。(不冒泡),在光标移动到后代元素上不会触发。但DOM3级级事件纳入了规范。IE、firefox9+和opera支持;

5. mouseleave:在元素上方的鼠标光标移动到元素范围之外时触发。这个事件不冒泡。而且在光标移动到后代元素上不会触发。DOM3级级事件纳入了规范。IE、firefox9+和opera支持;

6. mousemove:当鼠标指针在元素内部发生移动时触发;

7. mouseout:在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发。(注意了:)又移入的一个元素可能位于前一个元素的外部,也可能是这个元素的子元素。

8. mouseover:鼠标指针位于元素的外部,然后用户将其首次移入另一个元素边界之内时触发。

9. mouseup:用户释放鼠标按钮的时候触发。

总结:从上面可以了解到mouseover、mouseout和mouseenter、mouseleave用法差不多,但是mouseenter和mouseleave不支持冒泡。 检验如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #container{width:px;height:px;background-color:blueviolet;margin:px;}
        #container #content{width:px;height:px;background-color:firebrick;float: left;margin:px;}
    </style>
</head>
<body>
    <div id="container">
        <div id="content"></div>
    </div>
</body>
<script>
    var con = document.getElementById('container');
    var handler = function(event){
        switch(event.type){
            case 'mouseover' : console.log('mouseover');
                break;
            case 'mousemove' : console.log('mousemove');
                break;
            case 'mousedown' : console.log('mousedown');
                break;          
            case 'mouseup' : console.log('mouseup');
                break;
            case 'click' : console.log('click');
                break;
            case 'mouseout' : console.log('mouseout');
                break;
            case 'mouseenter' : console.log('mouseenter');
                break;
            case 'mouseleave' : console.log('mouseleave');
                break;
            case 'dblclick' : console.log('dblclick');
                break;
            case 'mousewheel' : console.log('mousewheel');
                break;  
        }
    }
//  con.addEventListener('mouseover',handler,false);
//  con.addEventListener('mousemove',handler,false);
//  con.addEventListener('mousedown',handler,false);
//  con.addEventListener('mouseup',handler,false);
//  con.addEventListener('click',handler,false);
//  con.addEventListener('mouseenter',handler,false);   //不支持冒泡
    con.addEventListener('mouseleave',handler,false);   //不支持冒泡
//  con.addEventListener('mouseout',handler,false);
    con.addEventListener('dblclick',handler,false);
</script>
</html>
           

如图所示:

js中的鼠标和滚轮事件 — 第13.4.3节

从上面可以看出,当一个div里面嵌套另一个div的时候,事件的触发顺序为:

1. mouseover 、mouseenter

2. mouseout、mouseover

3. mouseout、mouseover

4. mouseout、mouseleave

除了以上的事件,鼠标还支持mousewheel事件,如下所示:

二:检测是否支持鼠标事件的方法?

var isSupported2 = document.implementation.hasFeature('MouseEvents','2.0');
    var isSuuported3 = document.implementation;

    console.log(isSupported2)
    console.log(isSuuported3)
           

三:鼠标在各个容器中的属性?

以下调用的EventUtil的类都是来自封装后的兼容每个浏览器的事件处理代码:EventUtil类的js代码

1:相对于客户区的坐标位置?

   保存在event对象中的位置信息:clientX和clientY表示事件发生时鼠标指针在视口中的水平和垂直坐标。这些距离不包括页面滚动距离,仅仅相对于能看到的视口大小。

例如在div移动的指针相对于视口的位置:

EventUtil.addHandler(mdiv,'mousemove',function(event){
        event = EventUtil.getEvent(event);
        console.log("Client coordinates : " + event.clientX + "," + event.clientY);
    })
           

2:相对于页面的坐标位置?

   保存在event对象中的位置信息:pageX和pageY表示,事件是在页面中的什么位置发生的。换句话说,就是鼠标指针在页面中的位置,因此坐标的原点就是文档的左上角,可以超过视口的大小。

EventUtil.addHandler(mdiv,'mousemove',function(event){
        event = EventUtil.getEvent(event);
        console.log("Client coordinates : " + event.clientX + "," + event.clientY); //相对于视口位置
        console.log("Page coordinates : " + event.pageX + "," + event.pageY); //相对于页面位置
    })
           

由以上可以知道:当页面没有滚动的情况下,pageX和pageY的值和clientX和clientY的值相等。但是在ie8以及更早的版本中不支持pageX和pageY,这时候就需要用到document.body(混杂模式)或document.documentElement(标准模式)中的scrollLeft和scrollTop的属性,代码如下所示:

var mdiv = document.getElementById("myDiv");
    EventUtil.addHandler(mdiv,'click',function(event){
        event = EventUtil.getEvent(event);
        var pageX = event.pageX;
        var pageY = event.pageY;
        //以下是解决兼容性的代码
        var pageLeft = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft;
        var pageTop = document.body.scrollTop ? document.bodoy.scrollTop : document.documentElement.scrollTop;
        if(pageX === undefined){
            pageX = event.clientX + pageLeft;
        }
        if(pageY === undefined){
            pageY = event.clientY + pageTop; 
        }
        alert("Client coordinates : " + event.clientX + "," + event.clientY);
        alert("Page coordinates : " + pageX + "," + pageY);
    });
           

3:相对于屏幕坐标的位置?

   screenX和screenY 就是相对于终端屏幕的边缘的位置。原点为屏幕的左上角。

4:什么是修改键?

  修改键可能用到的不是太多,那么什么是修改键呢?当我们按着键盘上的一些键的同时,我们点击鼠标这时候就能显示出我们是否触发了修改键。DOM为此规定了4个属性用来表示修改键的状态:shiftKey、ctrlKey、altKey和metaKey。这些属性中包含的都是布尔值,如果相应的键被按下了在鼠标点击的同时,他们的值就会变为true。ie8及以下不支持这些属性。例子如下所示:

var mdiv = document.getElementById('myDiv');
    EventUtil.addHandler(mdiv,'click',function(event){
        var 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");
        }
        console.log("Keys:" + keys.join("和"));
        //当我按下ctrl和shift和alt的时候点击鼠标然后输出:Keys:shift和ctrl和alt
    })
           

5:什么是相关元素?

  在发生mouseover和mouseout事件的时候,会涉及到一些元素,这两个事件都会涉及到把鼠标指针从一个元素的边界移动到另一个元素的边界之内。对mouseover事件而言,相关元素就是失去光标的那个元素;对于mouseout事件而言,相关元素就是获得光标的元素。

在EventUatil对象中加入getRelatedTarget方法用来获取相关的元素,其种ie8之前版本不支持relatedTarget属性,但是在mouseover事件触发时IE的fromElement属性中个保存了相关元素,在mouseout事件出发时,IE的toElement属性保留了相关元素。兼容性处理如下:

getRelatedTarget:function(e){  //获取相关元素
        if(e.relatedTarget){
            return e.relatedTarget;
        }else if(e.toElement){
            return e.toElement;
        }else if(e.fromElement){
            return e.fromElement;
        }else{
            return null;
        }
    }
           

测试代码如下:

var mdiv = document.getElementById("myDiv");
    EventUtil.addHandler(mdiv,'mouseout',function(event){
        event = EventUtil.getEvent(event);
        var relElement = EventUtil.getRelatedTarget(event);
        var target = EventUtil.getTarget(event);
        console.log("mouse out of " + target.tagName + " to " + relElement.tagName);//mouse out of DIV to BODY
        console.log(event.relatedTarget.tagName)
        console.log(event.toElement.tagName)
        console.log(event.fromElement.tagName);
    })
           

6:什么是鼠标按钮属性?

  对于mousedown和mouseup事件来说,event对象存在一个button属性。表示按下或者释放按钮。DOM的button属性可能有如下3个值:0,左键,1中间键,2右键。ie8及之前的版本和DOM的button属性有很大差异:

0. 表示没有按下按钮;

1. 表示按下左键;

2. 按下右键;

3. 同时按下左右键;

4. 中间键;

5. 左键和中间键;

6. 右键和中间键;

7. 同时按下三个鼠标键。

在EventUtil中加入getButton方法: 兼容性处理如下:

getButton: function(e) { //使用mousedown和mouseup时使用
        if (document.implementation.hasFeature("MouseEvents", "20")) {
            return e.button;
        } else {
            switch (e.button) {
            case :
            case : 
            case :
            case :
            case :
                return ;
            case :
            case :
                return ;
            case :
                return ;
            }
        }
    }
           

使用代码:

var mdiv = document.getElementById('mdiv');
    EventUtil.addHandler(mdiv,'mouseup',function(event){
        event = EventUtil.getEvent(event);
        alert(EventUtil.getButton(event));
    });
           
  1. event对象中的detail和offset的用法?

      “DOM2级事件”中detail属性包含一个数值,表示在给定位置上发生了多次单击。其中mousedown和mouseup事件算一次单击。detail属性从1开始计数,每次单击之后就会增加。mousedown和mouseover之间移动了位置后,detail会被重置为0;因此我们可以通过detail来判断鼠标点击的次数。

      event中的offsetX和offsetY属性表示鼠标相对于元素边界的位置。

var mdiv = document.getElementById('mdiv');
        mdiv.addEventListener('click',function(e){
            console.log(e.offsetX + ',' + e.offsetY);
//          console.log(this.offsetWidth + ',' + this.offsetHeight);
//          console.log(this.scrollLeft + ',' + this.scrollTop);
            console.log(e.detail);
        },false)
           

8: 鼠标滚轮事件

   和mousewheel事件对应的event对象就是wheelDelta属性。通过wheelDelta的正负号来确定滚轮的方向。

var mdiv = document.getElementById('mdiv');
        mdiv.addEventListener('mousewheel',function(e){
            console.log(e.wheelDelta) //-120或120
        },false)
           

9:触摸设备的事件?

  在ios、Android设备中,需要知道:

  • 不支持dbclick事件。双击浏览器会放大画面;
  • 轻击可以单击的元素会触发mousemove事件。会以此发生mousedown、mouseup和click事件。轻击不可单击的元素不会触发任何事件;
  • mousemove事件也会触发mouseover和mouseout事件

推荐网址:获取元素的位置信息:

http://www.ruanyifeng.com/blog/2009/09/find_element_s_position_using_javascript.html

继续阅读