JS事件(7)——事件类型——鼠标与滚轮事件

鼠标与滚轮事件

鼠标事件

“DOM3级事件”中定义了9个鼠标事件。

click:在单击主鼠标按钮(一般是左键)或者按下回车时触发;这意味着onclick事件处理程序既可以通过鼠标也可以通过键盘执行。

dbclick:双击主鼠标按钮(一般是左键)或者按下回车键时触发。

mousedown:按下任意鼠标按钮时触发;不能通过键盘触发。

mouseup:释放鼠标按钮时触发;不能通过键盘触发。

mouseenter:在鼠标光标从元素外部首次移动到元素范围之内时触发;这个事件不冒泡,而且光标移动到元素的后代元素上不会触发;IE、Firefox9+和Opera支持这个事件。

mouseleave:在鼠标光标从元素上方移动到元素范围之外时触发;这个事件不冒泡,而且光标移动到元素的后代元素上不会触发;IE、Firefox9+和Opera支持这个事件。

mousemove:在鼠标光标在元素内部移动时重复地触发;不能通过键盘触发。

mouseout:在鼠标位于一个元素上方,然后移动到另一个元素时触发,另一个元素可以是这个元素的子元素;不能通过键盘触发。

mouseover:在鼠标位于一个元素外部,然后将其首次移动到另一个元素边界之内时触发;不能通过键盘触发。

只有在同一个元素上相继触发mousedown和mouseup,才会触发click事件;类似地,只有在同一个元素上触发两次click事件,才会触发一次dbclick事件。

这四个事件的触发顺序如下:

(1)mousedown

(2)mouseup

(3)click

(4)mousedown

(5)mouseup

(6)click

(7)dbclick

除了mouseenter、mouseleave、dbclick是“DOM3级事件”新增之外,其它事件都是“DOM2级事件”中定义的。

可以使用如下代码检测浏览器是否支持“DOM2级”鼠标事件:

1 var isSupported = document.implementation.hasFeature("MouseEvents", "2.0");
2 alert(isSupported);    //true

或者是否支持“DOM3级”鼠标事件:

1 var isSupported = document.implementation.hasFeature("MouseEvent", "3.0");
2 alert(isSupported);    //true

注意:“DOM3级”鼠标事件的feature名为MouseEvent;而“DOM2级”为MouseEvents。

客户区坐标位置

通过事件对象event的clientX和clientY属性,可以访问事件发生时鼠标指针在视窗中的水平和垂直坐标。

1 event_util.addHandler(document, "click", function(event) {
2     event = event_util.getEvent(event);
3     alert("鼠标指针客户区坐标为:水平距离—" + event.clientX + ";" + "垂直距离—" + event.clientY + "");
4 });

页面坐标位置

通过事件对象event的pageX和pageY属性,可以访问事件发生时鼠标指针在页面中的水平和垂直坐标。

1 event_util.addHandler(document, "click", function(event) {
2     event = event_util.getEvent(event);
3     alert("鼠标指针页面坐标为:水平距离—" + event.pageX + ";" + "垂直距离—" + event.pageY);
4 });

在页面没有滚动的情况下,pageX和pageY的值与clientX和clientY的值相等。

IE8中的页面坐标位置

IE8及更早版本不支持事件对象上的页面坐标,不过可以使用客户区坐标和滚动信息计算出来。

需要用到document.body(混杂模式)或者document.documentElement(标准模式)中的scrollLeft和scrollTop属性。

计算过程如下:

 1 event_util.addHandler(document, "click", function(event) {
 2     event = event_util.getEvent(event);
 3     var pageX = event.pageX;
 4     var pageY = event.pageY;
 5     if(pageX === undefined) {
 6         pageX = event.clientX + (document.body.scrollLeft || document.documentElememt.scrollLeft);
 7     };
 8     if(pageY === undefined) {
 9         pageY = event.clientY + (document.body.scrollTop || document.documentElememt.scrollTop);
10     };
11     alert("鼠标指针页面坐标为:水平距离—" + pageX + ";" + "垂直距离—" + pageY);
12 });

屏幕坐标位置

通过事件对象event的screenX和screenY属性,可以访问事件发生时鼠标指针在屏幕中的水平和垂直坐标。

1 event_util.addHandler(document, "click", function(event) {
2     event = event_util.getEvent(event);
3     alert("鼠标指针屏幕坐标为:水平距离—" + event.screenX + ";" + "垂直距离—" + event.screenY);
4 });

修改键

Shift、Ctrl、Alt、Meta(或Windows或Cmd),它们经常被用来修改鼠标事件的行为。

DOM为此规定了4个属性:shiftKey、ctrlKey、altKey、metaKey,表示这些修改键的状态。

这些属性中包含的都是布尔值,如果值为true,表示相应的键被按下。

当某个鼠标事件发生时,通过检测这4个属性,就能确定用户是否按下某个修改键。

 1 event_util.addHandler(document, "click", function(event) {
 2     event = event_util.getEvent(event);
 3     var keys = new Array();
 4     if(event.shiftKey) {
 5         keys.push("shift");
 6     };
 7     if(event.ctrlKey) {
 8         keys.push("ctrl");
 9     };
10     if(event.altKey) {
11         keys.push("alt");
12     };
13     if(event.metaKey) {
14         keys.push("meta");
15     };
16     alert("点击鼠标的同时按下了:" + keys.join(","));
17 });

点击鼠标的同时按下Windows键,检测不出来,为何?

IE9、Firefox、Safari、Chrome和Opera都支持这4个属性;IE8及更早版本不支持metaKey属性。

相关元素

对mouseover事件而言,事件的主目标就是获得光标的元素,而相关元素就是失去光标的那个元素;

对mouseout事件而言,事件的主目标就是失去光标的元素,而相关元素就是获得光标的那个元素。

DOM通过event事件对象的relatedTarget属性提供了相关元素的信息。

这个属性只对mouseover和mouseout事件才包含值;对于其他事件,其值为null。

IE8及之前版本不支持relatedTarget属性,但提供相似的属性。

在mouseover事件触发时,IE的fromElement属性中保存着相关元素;在mouseout事件触发时,IE的toElement属性中保存了相关元素。

IE9支持所有的这些属性。

将getRelatedTarge()方法添加到event_util对象中。

 1 getRelatedTarget: function(event) {
 2     if(event.relatedTarget) {
 3         return event.relatedTarget;
 4     } else if(event.fromElement) {
 5         return event.fromElement;
 6     } else if(event.toElement) {
 7         return event.toElement;
 8     } else {
 9         return null;
10     }
11 }

附上完整的event_util对象的代码:

 1 var event_util = {
 2     //添加事件
 3     addHandler: function(element, type, handler) {
 4         if(element.addEventListener) {
 5             element.addEventListener(type, handler, false);
 6         } else if(element.attachEvent) {
 7             element.attachEvent("on" + type, handler);
 8         } else {
 9             element["on" + type] = handler;
10         }
11     },
12     //移除事件
13     removeHandler: function(element, type, handler) {
14         if(element.removeEventListener) {
15             element.removeEventListener(type, handler, false);
16         } else if(element.detachEvent) {
17             element.detachEvent("on" + type, handler);
18         } else {
19             element["on" + type] = null;
20         }
21     },
22     //获取事件对象
23     getEvent: function(event) {
24         return event ? event : window.event;
25     },
26     //获取事件目标
27     getTarget: function(event) {
28         return event.target || event.srcElement;
29     },
30     //阻止事件冒泡
31     stopPropagation: function(event) {
32         if(event.stopPropagation) {
33             event.stopPropagation();
34         } else {
35             event.cancelBubble = true;
36         }
37     },
38     //取消事件默认行为
39     preventDefault: function(event) {
40         if(event.preventDefault) {
41             event.preventDefault();
42         } else {
43             event.returnValue = false;
44         }
45     },
46     //获取相关元素
47     getRelatedTarget: function(event) {
48         if(event.relatedTarget) {
49             return event.relatedTarget;
50         } else if(event.fromElement) {
51             return event.fromElement;
52         } else if(event.toElement) {
53             return event.toElement;
54         } else {
55             return null;
56         }
57     }
58 }

相关元素的示例:

1 var btn = document.getElementById("btn");
2 event_util.addHandler(btn, "mouseover", function(event) {
3     event = event_util.getEvent(event);
4     var relatedTarget = event_util.getRelatedTarget(event);
5     var target = event_util.getTarget(event);
6     alert("光标从" + relatedTarget.tagName + "移动到" + target.tagName);
7 });

注意:Javascript中的tagName都是大写。

鼠标按钮

对于mousedown和mouseup事件而言,在event事件对象中存在一个button属性,表示按下或释放的按钮。

DOM中的button属性可能有以下三个值:0,表示主鼠标按钮;1,表示中间按钮;2,表示次鼠标按钮。

IE8及之前版本中,也提供button属性,但其属性值与DOM的不太通属性值有很大差别。

再为event_util对象添加getButton()方法。

 1 getButton: function(event) {
 2     if(document.implementation.hasFeature("MouseEvents", "2.0")) {
 3         return event.button;
 4     } else {
 5         switch(event.button) {
 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 }

通过检测“MouseEvents”这个特性,就可以确定event对象中存在的button属性中是否包含正确的值;如果测试失败,说明是IE,就必须对相应的值进行规范化。

附上event_util对象的完整代码:

 1 var event_util = {
 2     //添加事件
 3     addHandler: function(element, type, handler) {
 4         if(element.addEventListener) {
 5             element.addEventListener(type, handler, false);
 6         } else if(element.attachEvent) {
 7             element.attachEvent("on" + type, handler);
 8         } else {
 9             element["on" + type] = handler;
10         }
11     },
12     //移除事件
13     removeHandler: function(element, type, handler) {
14         if(element.removeEventListener) {
15             element.removeEventListener(type, handler, false);
16         } else if(element.detachEvent) {
17             element.detachEvent("on" + type, handler);
18         } else {
19             element["on" + type] = null;
20         }
21     },
22     //获取事件对象
23     getEvent: function(event) {
24         return event ? event : window.event;
25     },
26     //获取事件目标
27     getTarget: function(event) {
28         return event.target || event.srcElement;
29     },
30     //阻止事件冒泡
31     stopPropagation: function(event) {
32         if(event.stopPropagation) {
33             event.stopPropagation();
34         } else {
35             event.cancelBubble = true;
36         }
37     },
38     //取消事件默认行为
39     preventDefault: function(event) {
40         if(event.preventDefault) {
41             event.preventDefault();
42         } else {
43             event.returnValue = false;
44         }
45     },
46     //获取相关元素
47     getRelatedTarget: function(event) {
48         if(event.relatedTarget) {
49             return event.relatedTarget;
50         } else if(event.fromElement) {
51             return event.fromElement;
52         } else if(event.toElement) {
53             return event.toElement;
54         } else {
55             return null;
56         }
57     },
58     //获取button属性值
59     getButton: function(event) {
60         if(document.implementation.hasFeature("MouseEvents", "2.0")) {
61             return event.button;
62         } else {
63             switch(event.button) {
64                 case 0:
65                 case 1:
66                 case 3:
67                 case 5:
68                 case 7:
69                     return 0;
70                 case 2:
71                 case 6:
72                     return 2;
73                 case 4:
74                     return 1;
75             }
76         }
77     }
78 }

鼠标按钮示例:

1 event_util.addHandler(document, "click", function(event) {
2     event = event_util.getEvent(event);
3     alert(event.button);
4 });

更多的事件信息

对于鼠标事件来说,detail属性中包含一个数值,表示在给定位置上发生多少次单击;在同一个位置上相继发生mousedown和mouseup事件算作一次单击。

detail从1开始计数。

如果鼠标在mousedown和mouseup事件之间移动了位置,则detail的值会被重置为0。

鼠标滚轮事件

mousewheel事件,可以在任何元素上触发,最终会冒泡到document(IE8)或window(IE9、Opera、Chrome和Safari)对象。

与mousewheel事件对应的event对象除了包含鼠标事件的所有标准信息之外,还包含一个特殊的wheelDelta属性;当用户向前滚动鼠标滚轮时,wheelDelta是10的倍数,当用户向后滚动鼠标滚轮时,wheelDelta是-120的倍数。

1 event_util.addHandler(document, "mousewheel", function(event) {
2     event = event_util.getEvent(event);
3     alert(event.wheelDelta);
4 });

多数情况下,只需要知道滚动鼠标滚轮的方向,而这通过检测wheelDelta的正负号就可以确定。

在Opera9.5及之前版本中,wheelDelta的正负号是颠倒的;可以使用浏览器检测技术来确定实际的值,如下:

1 event_util.addHandler(document, "mousewheel", function(event) {
2     event = event_util.getEvent(event);
3     var delta = (client.engine.opera && client.engine.opera < 9.5 ? -event.wheelDelta : event.wheelDelta)
4     alert(delta);
5 });

在Firefox浏览器中,支持一个名为DOMMouseScroll的事件,也是在鼠标滚轮滚动时触发,其被视为鼠标事件,包含与鼠标事件有关的所有信息;而有关鼠标滚轮的信息则保存在detail属性中,当向前滚动滚轮时,其值为-3的倍数,当向后滚动滚轮时,其值为3的倍数。

可以将DOMMouseScroll事件添加到页面中的任何元素,而且该事件会冒泡到window对象。

1 event_util.addHandler(document, "DOMMouseScroll", function(event) {
2     event = event_util.getEvent(event);
3     alert(event.detail);
4 });

跨浏览器的解决方案

首先,创建一个能够取得鼠标滚轮增量值(delta)的方法getWheelDelta()。

1 getWheelDelta: function(event) {
2     if(event.wheelDelta) {
3         return event.wheelDelta;
4     } else {
5         return -event.detail * 40;
6     }
7 }

首先检测事件中是否包含wheelDelta属性,如果是,则通过wheelDelta属性返回值;如果不存在wheelDelta属性,则假设相应的值保存在detail属性中,将这个值取反然后乘以40,就可以得到与其它浏览器相同的值。

上述代码暂不考虑Opera9.5及之前的情况。

将这个方法添加到event_util对象中;附上event_util对象完整代码:

 1 var event_util = {
 2     //添加事件
 3     addHandler: function(element, type, handler) {
 4         if(element.addEventListener) {
 5             element.addEventListener(type, handler, false);
 6         } else if(element.attachEvent) {
 7             element.attachEvent("on" + type, handler);
 8         } else {
 9             element["on" + type] = handler;
10         }
11     },
12     //移除事件
13     removeHandler: function(element, type, handler) {
14         if(element.removeEventListener) {
15             element.removeEventListener(type, handler, false);
16         } else if(element.detachEvent) {
17             element.detachEvent("on" + type, handler);
18         } else {
19             element["on" + type] = null;
20         }
21     },
22     //获取事件对象
23     getEvent: function(event) {
24         return event ? event : window.event;
25     },
26     //获取事件目标
27     getTarget: function(event) {
28         return event.target || event.srcElement;
29     },
30     //阻止事件冒泡
31     stopPropagation: function(event) {
32         if(event.stopPropagation) {
33             event.stopPropagation();
34         } else {
35             event.cancelBubble = true;
36         }
37     },
38     //取消事件默认行为
39     preventDefault: function(event) {
40         if(event.preventDefault) {
41             event.preventDefault();
42         } else {
43             event.returnValue = false;
44         }
45     },
46     //获取相关元素
47     getRelatedTarget: function(event) {
48         if(event.relatedTarget) {
49             return event.relatedTarget;
50         } else if(event.fromElement) {
51             return event.fromElement;
52         } else if(event.toElement) {
53             return event.toElement;
54         } else {
55             return null;
56         }
57     },
58     //获取button属性值
59     getButton: function(event) {
60         if(document.implementation.hasFeature("MouseEvents", "2.0")) {
61             return event.button;
62         } else {
63             switch(event.button) {
64                 case 0:
65                 case 1:
66                 case 3:
67                 case 5:
68                 case 7:
69                     return 0;
70                 case 2:
71                 case 6:
72                     return 2;
73                 case 4:
74                     return 1;
75             }
76         }
77     },
78     //获取鼠标滚轮增量值
79     getWheelDelta: function(event) {
80         if(event.wheelDelta) {
81             return event.wheelDelta;
82         } else {
83             return -event.detail * 40;
84         }
85     }
86 }

定义一个handleWheelDelta函数,作为一个事件处理程序,可以同时应对FIrefox中的“DOMMouseScroll”事件和非Firefox中的“mousewheel”事件。

1 function handleMouseWheel(event) {
2     event = event_util.getEvent(event);
3     var delta = event_util.getWheelDelta(event);
4     alert(delta);
5 }

可以使用以下代码来添加事件:

1 event_util.addHandler(document, "DOMMouseScroll", handleMouseWheel);
2 event_util.addHandler(document, "mousewheel", handleMouseWheel);

可以进一步将这些代码放在一个私有作用域中,从而不会让新定义的函数干扰全局作用域。

1 (function() {
2     function handleMouseWheel(event) {
3         event = event_util.getEvent(event);
4         var delta = event_util.getWheelDelta(event);
5         alert(delta);
6     }
7     event_util.addHandler(document, "DOMMouseScroll", handleMouseWheel);
8     event_util.addHandler(document, "mousewheel", handleMouseWheel);
9 })();

触摸设备

(1)不支持dbclick事件。双击浏览器窗口会放大画面,而且没有办法改变该行为。

(2)轻击可单击元素会触发mouseover事件。如果此操作导致内容变化,则不会再有其它事件发生;如果屏幕没有发生变化,则依次发生mousedown、mouseup、click事件。

(3)mousemove事件也会触发mouseover和mouseout事件。

(4)两个手指放在屏幕上且页面随手指移动而滚动时会触发mousewheel和scroll事件。

无障碍性问题

可以通过键盘上的回车键来触发click事件,而其它鼠标事件都不能通过键盘触发;因此,不建议使用其它鼠标事件来展示功能或引发代码执行,因为这样会给屏幕阅读器用户造成极大不便。

使用鼠标事件时应注意的几个易访问性问题:

(1)使用click事件执行代码。

(2)不要使用mouseover向用户显示新的选项;如果确实需要通过这种方式来显示,可以考虑添加显示相同信息的键盘快捷方式。

(3)不要使用dbclick执行重要的操作;键盘无法触发这个事件。

时间: 2024-08-08 09:56:53

JS事件(7)——事件类型——鼠标与滚轮事件的相关文章

javaScript事件——鼠标与滚轮事件

以下事件中,没有说明键盘能触发的表示键盘不能触发,没有指明不冒泡的表示冒泡. click:单击事件,Enter 键也能触发. dblclick:双击事件. mousedown:鼠标按下事件,任意鼠标按钮被按下都能触发. mouseup:任意鼠标按钮被释放时触发. mouseenter:光标首次进入到某一元素内部时触发.无论光标有没有直接在此元素上,只要光标进入它的边界,则触发.不冒泡. mouseleave:光标离开元素内部时触发.不冒泡. mousemove:光标在元素内部移动时重复触发. m

鼠标和滚轮事件

1.可以通过以下代码取得鼠标事件的客户端坐标信息; var btn = document.getElementById("btn"); EventUtil.addHandler(btn,"click",function(event){ event = EventUtil.getEvent(event); alert("client coordinates:" + event.clientX+","+event.clientY)

JS事件-鼠标滚轮事件

之前学习了onmouseover,onmousedown等鼠标事件,今天来看看鼠标的滚轮事件,浏览器兼容一直是让人比较恶心的事情,今天就让我们将恶心进行到底,看看这个恶心的鼠标滚轮事件! 鼠标滚轮事件在IE和谷歌浏览器Chrome下是通过onmousewheel这个事件实现的,但是火狐FF下却不识别onmousewheel,在FF下需要用DOMMouseScroll,并且必须用"事件监听"方式添加事件才有效: 而大家都知道"事件监听"方式绑定事件: IE下是通过at

Winform 中panel的mousewheel鼠标滚轮事件触发

如果将窗体或容器控件(如Panel控件)的AutoScroll属性设置为True时,那么当窗体或Panel容不下其中的子控件时就会出现 滚动条,通过移动滚动条可以上下显示出窗体或Panel中的全部内容.但是默认情况下滚动条的移动只能通过鼠标直接拖动滚动条来实现,而不能通过鼠标的滚 轮来实现上下移动,因此需要手动添加代码来实现这个功能. 滚动鼠标的滚轮,触发的是窗体或控件上的 MouseWheel 事件.但是在VS.net2005中,窗体和控件的事件列表中却不包含 MouseWheel 事件,因此

JavaScript鼠标滚轮事件

IE6.0首先实现了鼠标的滚轮事件,其良好的交互效果得到认可,随后Opera.chrome.safari等主流浏览器都实现了该效果,不过存在着很大的兼容问题. 大多数浏览器支持mousewheel事件操作,它可以在任何元素上触发,最终冒泡到document或window对象:而在Firefox中,支持的是另外一种事件——DOMMouseScroll,其中最为特殊的是它必须用addEventListener方法实现,故一般进行如下处理 mousewheel触发事件会有一个特殊的事件属性——whee

js中鼠标滚轮事件详解

(以下内容部分内容参考了http://adomas.org/javascript-mouse-wheel/ ) 之前js 仿Photoshop鼠标滚轮控制输入框取值中已使用js对鼠标滚轮事件进行控制,滚轮事件其中考虑浏览器兼容性问题 附加事件 其中经我测试,IE/Opera属于同一类型,使用attachEvent即可添加滚轮事件. /*IE注册事件*/ if(document.attachEvent){ document.attachEvent('onmousewheel',scrollFunc

JS鼠标滚轮事件解析

一.不同浏览器的鼠标滚轮事件 首先,不同的浏览器有不同的滚轮事件.主要是有两种,onmousewheel(IE/Opera/Chrome支持,firefox不支持)和DOMMouseScroll(只有firefox支持) 另外在操作的过程中需要添加事件监听,兼容性写法 代码如下: /*注册事件*/ if(document.addEventListener){ document.addEventListener('DOMMouseScroll',scrollFunc,false); // W3C

js整频滚动展示效果(函数节流鼠标滚轮事件)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head> <meta http-equiv="Content-T

js中的鼠标滚轮事件

## 事件对象 event 1 event事件对象,表示用来获取事件的详细信息,比如得到鼠标的横坐标:事件对象.clientX(clientX是可视区坐标) window.onclick = function(ev){ var oEvent = ev || event;//event为IE8和IE8以下浏览器浏览器事件对象可以直接使用: //以上代码可以判断是否传递了事件对象参数,如果传递了则使用传递的事件对象ev,否则使用window.event alert(oEvent.type);//cl