滚轮事件其实就是一个mousewheel事件,这个事件跟踪鼠标滚轮,类似Mac的触屏版。
一、客户区坐标位置
鼠标事件都是在浏览器视口的特定位置上发生的。这个位置信息保存在事件对象的clientX和clientY属性中。所有浏览器都支持者两个属性。clientX和clientY表示事件发生时鼠标指针在视口中的水平和垂直坐标。
1
2
3
4 1document.addEventListener('click',function(event){
2 document.title=event.clientX+' , '+event.clientY;
3},false);
4
给document指定了onclick事件处理程序,单击页面时在title中可以看到客户端的坐标信息。
注意:这些值中不包括页面滚动的距离,因为这个位置并不表示鼠标在页面上的位置。
二、页面坐标位置
通过clientX和clientY能够指定鼠标是在视口中声明位置发生的,而页面坐标通过事件对象的pageX和pageY属性,能够得到事件是在页面中的什么位置发生的。即pageX和pageY表示鼠标光标在页面中的位置,因此坐标是从页面本身而非视口的左边和顶边计算的。
1
2
3
4
5 1document.addEventListener('click',function(event){
2 console.log(event.clientX+' , '+event.clientY);
3 console.log(event.pageX+' , '+event.pageY);
4},false);
5
在页面没有滚动的情况下,pageX和pageY的值与clientX和clientY的值相等。
IE8及更早版本不支持事件对象上的页面坐标,不过使用客户区坐标和滚动信息可以计算出来。这时候需要用到document.body(混杂模式)或document.documentElement(标准模式)中的scrollLeft和scrollTop属性。如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 1<script type="text/javascript">
2var div=document.getElementById("myDiv");
3EventUtil.addHandler(div,"click",function(event){
4 event=EventUtil.getEvent(event);
5 var pageX=event.pageX,
6 pageY=event.pageY;
7 if(pageX==undefined) {
8 pageX=event.clientX+(document.body.scrollLeft || document.documentElement.scrollLeft);
9 }
10 if(pageY==undefined){
11 pageY=event.clientY+(document.body.scrollTop || document.documentElement.scrollTop);
12 }
13 alert("Page coordinates:" +pageX+" , "+pageY);
14});
15</script>
16
三、屏幕坐标位置
鼠标事件发生时,不仅会有相对于浏览器窗口的位置,还有一个相对于整个电脑屏幕的位置。而通过screenX和screenY属性就可以确定鼠标事件发生时鼠标指针相对于整个屏幕的坐标信息。
1
2
3
4
5
6 1document.addEventListener('click',function(event){
2 console.log("Client coordinates"+event.clientX+' , '+event.clientY);
3 console.log("Page coordinates "+event.pageX+' , '+event.pageY);
4 console.log("Screen coordinates "+event.screenX+' , '+event.screenY);
5},false);
6
四、修改键
虽然鼠标事件主要是使用鼠标来触发的,但在按下鼠标时键盘上的某些键的状态也可以影响到所要采取的操作。这些修改键就是Shift、Ctrl、Alt和Meta(在Windows键盘中是Windows键,在苹果机中是Cmd键) ,它们通常被用来修改鼠标事件的行为。
DOM为此规定了4个属性,表示这些修改键的状态:shiftKey,ctrlKey,altKey和metaKey。这些属性中包含的都是布尔值,如果相应的键被按下了,则值为true,否则值为false。当某个鼠标事件发生时,通过检测这几个属性就可以确定用户是否同时按下了其中的键。如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 1<script type="text/javascript">
2var div=document.getElementById("myDiv");
3EventUtil.addHandler(div,"click",function(event){
4 event=EventUtil.getEvent(event);
5 var keys=new Array();
6
7 if(event.shiftKey){
8 keys.push("shift");;
9 }
10 if(event.ctrlKey){
11 keys.push("ctrl");
12 }
13 if(event.altKey){
14 keys.push("alt");
15 }
16 if(event.metaKey){
17 keys.push("meta");
18 }
19
20 alert("Keys: "+keys.join(","));
21});
22</script>
23
通过一个onclick事件处理程序检测了不同修改键的状态。数组keys中包含着被按下的修改键的名称。也就是说,如果有属性值为true,就会将对应修改键的名称添加到keys数组中。在事件处理程序的最后,有一个警告框将检测到的键的信息显示给用户。
Note:IE8及之前的版本不支持metaKey属性,IE9、Firefox、Safari、Chrome和Opera都支持这4个键。
五、相关元素
在发生mouseover和mouseout事件时,还会涉及更多的元素。这两个事件都会涉及把鼠标指针从一个元素的边界之内移动到另一个元素的边界之内。
对mouseover事件而言,事件的主目标是获得光标的元素,而相关元素就是那个失去光标的元素。
类似地,对mouseout事件而言,事件的主目标是失去光标的元素,而相关元素是获得光标的元素。
DOM通过event对象的relatedTarget属性获得相关元素的信息。relatedTarget属性只对mouseover和mouseout事件才包含值;对于其他事件,这个属性值是null。
IE8及之前版本不支持relatedTarget属性,但提供了保存着相同信息的不同属性。
在mouseover事件触发时,IE的fromElement属性中保存了相关元素;
在mouseout事件触发时,IE的toElement属性保存了相关元素;(IE9支持relatedTarget,fromElement,toElement都支持)
例子:
1
2 1<div id="myDiv" style="background-color: red;height: 100px;width: 100px;"></div>
2
1
2
3
4
5
6
7
8 1var div=document.getElementById("myDiv");
2EventUtil.addHandler(div,"mouseout",function(event){
3 event=EventUtil.getEvent(event);
4 var target=EventUtil.getTarget(event);
5 var relatedTarget=EventUtil.getRelatedTarget(event);
6 alert("Moused out of "+target.nodeName+" to "+relatedTarget.tagName);
7});
8
六、鼠标按钮
对于mousedown和mouseup事件,在event对象中存在一个button属性,表示按下或释放的按钮。
DOM的button属性有3个取值:
- 0:表示主鼠标按钮(鼠标左键)
- 1:表示中间的鼠标按钮(鼠标滚轮按钮)
- 2:表示次鼠标按钮(鼠标右键)
IE8及之前版本也提供了button属性,但这个属性的值与DOM的button属性有很大差异。
- 0:表示没有按按钮。——》
0
- 1:表示按下了鼠标左键——》0
- 2:表示按下了鼠标右键——》2
- 3:表示同时按下了鼠标左右键——》0
- 4:表示按下了中间的鼠标按钮——》1
- 5:表示同时按下了鼠标左键和中间的鼠标按钮——》0
- 6:表示同时按下了鼠标右键和中间的鼠标按钮——》2
- 7:表示同时按下了三个鼠标按钮——》》DOM0
DOM模型下的button属性比IE模型下的button属性更简单实用,因为同时按下多个鼠标按钮的情形十分罕见。
最常见的的做法就是将IE模型规范化为DOM方式,毕竟除IE8及更早版本之外都支持DOM模型。
将IE中其他选项分别转换成如同按下这三个按键中的一个即可(同时将主按钮作为优先选取的对象)。
IE中返回的5和7会被转换成DOM模型中的0。
重点:由于单独使用能力检测无法确定差异(两种模型有同名的button属性) ,因此必须另辟蹊径。支持DOM版鼠标事件的浏览器可以通过hasFeature()方法来检测,所以跨浏览器的getButton()方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 1getButton:function(event){
2 if(document.implementation.hasFeature("MouseEvents","2.0")){
3 return event.button;
4 }else{
5 switch(event.buton){
6 case 0:
7 case 1:
8 case 3:
9 case 5:
10 case 7:
11 return 0;
12 case 2:
13 case 6:
14 return 2;
15 case 4:
16 return 1;
17 }
18 }
19
20 }
21
View Code
document.implementation.hasFeature("MouseEvents","2.0"))通过检测"MouseEvents"这个特性,就可以确定event对象中存在的button属性中是否包含正确的值。
Note:在onmouseup事件处理程序时,button值表示释放的是哪个按钮。此外,如果不是按下或释放了主鼠标按钮,Opera不会触发mouseup或mousedown事件。
七、更多的事件信息
“DOM2级事件”规范在event对象中还提供了detail属性,用于给出有关事件的更多信息。对于鼠标事件来说,detail中包含了一个数值,表示在给定位置上发生了多少次单击。
在同一个像素上相继地发生一次mousedown和一次mouseup事件算作一次单击。detail属性从1开始计数,每次单击递增。如果鼠标在mousedown和mouseup之间移动了位置,则detail会被重置为0。
八、鼠标滚轮事件
当用户通过是不滚轮与页面交互,在垂直方向上滚动页面时(无论向上还是向下),就会触发mousewheel事件。由于mousewheel事件非常流行,而且所有浏览器都支持它,所以HTML5也加入了mousewheel事件。
mousewheel事件可以在任何元素上面触发,最终会冒泡到document(IE8)或者window(IE9,Opera,Chrome及Safari)对象。
相关属性:除了鼠标事件的所有标准信息外,mousewheel事件对应的event对象还包含一特殊的wheelDelta属性。
当用户向前滚动鼠标滚轮时,wheelDelta是120的倍数;当用户向后滚动鼠标滚轮时,wheelDelta是-120的倍数。
多数情况,只需要知道鼠标滚轮滚动的方向即可,这通过wheelDelta的正负号实现。
兼容性:
Opera 9.5之前的版本,wheelDelta值的正负号是颠倒的。
Firefox支持一个DOMMouseScroll的类似事件,也是在鼠标滚轮轮滚动时触发。鼠标有关信息保存在detail属性中。当向前滚动鼠标滚轮时,这个属性的值是-3的倍数,向后滚动鼠标滚轮时,这个值是3的倍数。
以下为兼容性处理。
1
2
3
4
5
6
7
8 1getWheelDelta:function(event){
2 if(event.wheelDelta){
3 return(client.engine.opera && client.engine.opera<9.5? -event.wheelDelta:event.wheelDelta);
4 }else{
5 return -event.detail*40;
6 }
7}
8
九、触摸设备
iPhone和iPad没有鼠标。
- 不支持dblclick事件。双击浏览器窗口会放大画面,而且没有办法改变该行为。
- 轻击可单击元素会触发mousemove事件。如果此操作会导致内容变化,将不再有其他事件发生;如果屏幕没有因此变化,那么会依次触发mousedown,mouseup和click事件。轻击不可单击元素不会触发任何事件。可单击的元素是指那些可以单击产生默认操作的元素(如链接),或者那些已经被指定了onclik事件处理程序的元素。
- mousemove事件也会触发mouseover和mouseout事件。
- 两个手指放在屏幕上且页面随手指移动而滚动时会触发mousewheel和scroll事件。