JS鼠标与滚轮事件

鼠标事件是 Web 开发中最常用的一类事件,毕竟鼠标还是最主要的定位设备。DOM3 级事件中定义了 9 个鼠标事件.

click :在用户单击主鼠标按钮(一般是左边的按钮)或者按下回车键时触发。这一点对确保易访问性很重要,意味着 onclick 事件处理程序既可以通过键盘也可以通过鼠标执行。
dblclick :在用户双击主鼠标按钮(一般是左边的按钮)时触发。从技术上说,这个事件并不是 DOM2 级事件规范中规定的,但鉴于它得到了广泛支持,所以 DOM3 级事件将其纳入了标准
mousedown :在用户按下了任意鼠标按钮时触发。不能通过键盘触发这个事件
mouseenter :在鼠标光标从元素外部首次移动到元素范围之内时触发。这个事件不冒泡,而且在光标移动到后代元素上不会触发。DOM2 级事件并没有定义这个事件,但 DOM3 级事件将它纳入了规范。IE、Firefox 9+和 Opera 支持这个事件。
mouseleave :在位于元素上方的鼠标光标移动到元素范围之外时触发。这个事件不冒泡,而且在光标移动到后代元素上不会触发。DOM2 级事件并没有定义这个事件,但 DOM3 级事件将它纳入了规范。IE、Firefox 9+和 Opera 支持这个事件。
mousemove :当鼠标指针在元素内部移动时重复地触发。不能通过键盘触发这个事件
mouseout :在鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发。又移入的另一个元素可能位于前一个元素的外部,也可能是这个元素的子元素。不能通过键盘触发这个事件。
mouseover :在鼠标指针位于一个元素外部,然后用户将其首次移入另一个元素边界之内时触发。不能通过键盘触发这个事件。
mouseup :在用户释放鼠标按钮时触发。不能通过键盘触发这个事件

页面上的所有元素都支持鼠标事件。除了 mouseenter 和 mouseleave ,所有鼠标事件都会冒泡,也可以被取消,而取消鼠标事件将会影响浏览器的默认行为。取消鼠标事件的默行为还会影响其他事件,因为鼠标事件与其他事件是密不可分的关系。
只有在同一个元素上相继触发 mousedown 和 mouseup 事件,才会触发 click 事件;如果mousedown 或 mouseup 中的一个被取消,就不会触发 click 事件。类似地,只有触发两次 click 事件,才会触发一次 dblclick 事件。如果有代码阻止了连续两次触发 click 事件(可能是直接取消 click事件,也可能通过取消 mousedown 或 mouseup 间接实现),那么就不会触发 dblclick 事件了。这 4个事件触发的顺序始终如下:
(1)mousedown
(2)mouseup
(3)click
(4)mousedown
(5)mouseup
(6)click
(7)dbclick
显然,, click 和 dblclick 事件都会依赖于其他先行事件的触发;而 mousedown 和 mouseup 则不受其他事件的影响。
IE8 及之前版本中的实现有一个小 bug,因此在双击事件中,会跳过第二个 mousedown 和 click
事件,其顺序如下:
(1) mousedown
(2) mouseup
(3) click
(4) mouseup
(5) dblclick
IE9 修复了这个 bug,之后顺序就正确了。
要检测浏览器是否支持上面的所有事件,可以使用以下代码:

var isSupported = document.implementation.hasFeature("MouseEvent", "3.0")

鼠标事件中还有一类滚轮事件。而说是一类事件,其实就是一个 mousewheel 事件。这个事件跟踪鼠标滚轮,类似于 Mac 的触控板。
1. 客户区坐标位置
鼠标事件都是在浏览器视口中的特定位置上发生的。这个位置信息保存在事件对象的 clientX 和clientY 属性中。所有浏览器都支持这两个属性,它们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标。

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
event = EventUtil.getEvent(event);
alert("Client coordinates: " + event.clientX + "," + event.clientY);
});
  1. 页面坐标位置
    通过客户区坐标能够知道鼠标是在视口中什么位置发生的,而页面坐标通过事件对象的 pageX 和
    pageY 属性,能告诉你事件是在页面中的什么位置发生的。换句话说,这两个属性表示鼠标光标在页面
    中的位置,因此坐标是从页面本身而非视口的左边和顶边计算的。
    以下代码可以取得鼠标事件在页面中的坐标:
var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
event = EventUtil.getEvent(event);
alert("Page coordinates: " + event.pageX + "," + event.pageY);
});

在页面没有滚动的情况下, pageX 和 pageY 的值与 clientX 和 clientY 的值相等。
3. 屏幕坐标位置
鼠标事件发生时,不仅会有相对于浏览器窗口的位置,还有一个相对于整个电脑屏幕的位置。而通
过 screenX 和 screenY 属性就可以确定鼠标事件发生时鼠标指针相对于整个屏幕的坐标信息.
可以使用类似下面的代码取得鼠标事件的屏幕坐标:

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
event = EventUtil.getEvent(event);
alert("Screen coordinates: " + event.screenX + "," + event.screenY);
});
  1. 修改键
    虽然鼠标事件主要是使用鼠标来触发的,但在按下鼠标时键盘上的某些键的状态也可以影响到所要采取的操作。这些修改键就是 Shift、Ctrl、Alt 和 Meta(在 Windows键盘中是 Windows键,在苹果机中是 Cmd 键),它们经常被用来修改鼠标事件的行为。DOM 为此规定了 4 个属性,表示这些修改键的状态: shiftKey 、 ctrlKey 、 altKey 和 metaKey 。这些属性中包含的都是布尔值,如果相应的键被按下了,则值为 true ,否则值为 false 。当某个鼠标事件发生时,通过检测这几个属性就可以确定用户是否同时按下了其中的键。来看下面的例子。
var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "click", function(event){
event = EventUtil.getEvent(event);
var keys = new Array();
if (event.shiftKey){
keys.push("shift");
}
if (event.ctrlKey){
keys.push("ctrl");
}
if (event.altKey){
keys.push("alt");
}
if (event.metaKey){
keys.push("meta");
}
alert("Keys: " + keys.join(","));
});

在这个例子中,我们通过onclick 事件处理程序检测了不同修改键的状态。数组keys 中包含着被按下的修改键的名称。换句话说,如果有属性值为 true ,就会将对应修改键的名称添加到 keys数组中。在事件处理程序的最后,有一个警告框将检测到的键的信息显示给用户
5. 相关元素
在发生 mouseover 和 mouserout 事件时,还会涉及更多的元素。这两个事件都会涉及把鼠标指针从一个元素的边界之内移动到另一个元素的边界之内。mouseover 事件而言,事件的主目标是获得光标的元素,而相关元素就是那个失去光标的元素。类似地,对 mouseout 事件而言,事件的主目标是失去光标的元素,而相关元素则是获得光标的元素。来看下面的例子。

<!DOCTYPE html>
<html>
<head>
<title>Related Elements Example</title>
</head>
<body>
<div id="myDiv" style="background-color:red;height:100px;width:100px;"></div>
</body>
</html>

这个例子会在页面上显示一个<div> 元素。如果鼠标指针一开始位于这个<div>元素上,然后移出
了这个元素,那么就会在<div> 元素上触发 mouseout 事件,相关元素就是 <body> 元素。与此同时,
<body> 元素上面会触发 mouseover 事件,而相关元素变成了 <div>

DOM通过 event 对象的 relatedTarget 属性提供了相关元素的信息。这个属性只对于 mouseover和 mouseout 事件才包含值;对于其他事件,这个属性的值是 null 。IE8及之前版本不支持 relatedTarge属性,但提供了保存着同样信息的不同属性。在 mouseover 事件触发时,IE的 fromElement 属性中保存了相关元素;在mouseout 事件触发时,IE的 toElement 属性中保存着相关元素。(IE9支持所有这些属性。)可以把下面这个跨浏览器取得相关元素的方法添加到 EventUtil 对象中。

var EventUtil = {
//省略了其他代码
getRelatedTarget: function(event){
if (event.relatedTarget){
return event.relatedTarget;
} else if (event.toElement){
return event.toElement;
} else if (event.fromElement){
return event.fromElement;
} else {
return null;
}
},
//省略了其他代码
};//具体的代码请参照js事件那一篇文章

与以前添加的跨浏览器方法一样,这个方法也使用了特性检测来确定返回哪个值。可以像下面这样使用 EventUtil.getRelatedTarget() 方法:

var div = document.getElementById("myDiv");
EventUtil.addHandler(div, "mouseout", function(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
var relatedTarget = EventUtil.getRelatedTarget(event);
alert("Moused out of " + target.tagName + " to " + relatedTarget.tagName);
});
  1. 鼠标按钮
    只有在主鼠标按钮被单击(或键盘回车键被按下)时才会触发 click 事件,因此检测按钮的信息并不是必要的。但对于 mousedown 和 mouseup 事件来说,则在其 event 对象存在一个 button 属性,表示按下或释放的按钮。DOM 的 button 属性可能有如下 3 个值: 0 表示主鼠标按钮, 1 表示中间的鼠标按钮(鼠标滚轮按钮), 2 表示次鼠标按钮。在常规的设置中,主鼠标按钮就是鼠标左键,而次鼠标
    按钮就是鼠标右键。
    IE8 及之前版本也提供了 button 属性,但这个属性的值与 DOM 的 button 属性有很大差异
    0 :表示没有按下按钮。
    1 :表示按下了主鼠标按钮。
    2 :表示按下了次鼠标按钮。
    3 :表示同时按下了主、次鼠标按钮。
    4 :表示按下了中间的鼠标按钮。
    5 :表示同时按下了主鼠标按钮和中间的鼠标按钮。
    6 :表示同时按下了次鼠标按钮和中间的鼠标按钮。
    7 :表示同时按下了三个鼠标按钮。
    不难想见,DOM模型下的 button 属性比 IE 模型下的 button 属性更简单也更为实用,因为同时按下多个鼠标按钮的情形十分罕见。最常见的做法就是将 IE 模型规范化为 DOM 方式,毕竟除 IE8 及更早版本之外的其他浏览器都原生支持 DOM模型。而对主、中、次按钮的映射并不困难,只要将 IE 的其他选项分别转换成如同按下这三个按键中的一个即可(同时将主按钮作为优先选取的对象)。换句话说,
    IE 中返回的 5 和 7 会被转换成 DOM 模型中的 0 。
  2. 更多的事件信息
    “DOM2 级事件”规范在 event 对象中还提供了 detail 属性,用于给出有关事件的更多信息。对
    于鼠标事件来说, detail 中包含了一个数值,表示在给定位置上发生了多少次单击。在同一个元素上
    相继地发生一次 mousedown 和一次 mouseup 事件算作一次单击。 detail 属性从 1 开始计数,每次单
    击发生后都会递增。如果鼠标在 mousedown 和 mouseup 之间移动了位置,则 detail 会被重置为 0 。
    IE 也通过下列属性为鼠标事件提供了更多信息。
    altLeft :布尔值,表示是否按下了 Alt键。如果 altLeft 的值为 true ,则 altKey 的值也为 true 。
    offsetX :光标相对于目标元素边界的 x 坐标。
    offsetY :光标相对于目标元素边界的 y 坐标。
    shiftLeft :布尔值,表示是否按下了 Shift 键。如果 shiftLeft 的值为 true ,则 shiftKey的值也为 true 。
    这些属性的用处并不大,原因一方面是只有 IE 支持它们,另一方是它们提供的信息要么没有什么价值,要么可以通过其他方式计算得来。
    1. 鼠标滚轮事件
      IE 6.0 首先实现了 mousewheel 事件。此后,Opera、Chrome 和 Safari 也都实现了这个事件。当用户通过鼠标滚轮与页面交互、在垂直方向上滚动页面时(无论向上还是向下),就会触发 mousewheel事件。这个事件可以在任何元素上面触发,最终会冒泡到 document (IE8)或 window (IE9、Opera、Chrome 及 Safari)对象。与 mousewheel 事件对应的 event 对象除包含鼠标事件的所有标准信息外,还包含一个特殊的 wheelDelta 属性。当用户向前滚动鼠标滚轮时, wheelDelta 是 120 的倍数;当用户向后滚动鼠标滚轮时, wheelDelta 是-120 的倍数。
      将 mousewheel 事件处理程序指定给页面中的任何元素或 document 对象,即可处理鼠标滚轮的
      交互操作。来看下面的例子。
      EventUtil.addHandler(document, “mousewheel”, function(event){
      event = EventUtil.getEvent(event);
      alert(event.wheelDelta);
      });
      这个例子会在发生 mousewheel 事件时显示 wheelDelta 的值。多数情况下,只要知道鼠标滚轮滚动的方向就够了,而这通过检测 wheelDelta 的正负号就可以确定。
      有一点要注意:在 Opera 9.5 之前的版本中, wheelDelta 值的正负号是颠倒的。如果你打算支持早期的 Opera 版本,就需要使用浏览器检测技术来确定实际的值,如下面的例子所示。
EventUtil.addHandler(document, "mousewheel", function(event){
event = EventUtil.getEvent(event);
var delta = (client.engine.opera && client.engine.opera < 9.5 ?
-event.wheelDelta : event.wheelDelta);
alert(delta);
});

可以将 DOMMouseScroll 事件添加到页面中的任何元素,而且该事件会冒泡到 window 对象。因此,可以像下面这样针对这个事件来添加事件处理程序。

EventUtil.addHandler(window, "DOMMouseScroll", function(event){
event = EventUtil.getEvent(event);
alert(event.detail);
});
  1. 触摸设备
    iOS 和 Android 设备的实现非常特别,因为这些设备没有鼠标。在面向 iPhone 和 iPod 中的 Safari开发时,要记住以下几点。
    不支持 dblclick 事件。双击浏览器窗口会放大画面,而且没有办法改变该行为。
    轻击可单击元素会触发 mousemove 事件。如果此操作会导致内容变化,将不再有其他事件发生;
    如果屏幕没有因此变化,那么会依次发生 mousedown 、 mouseup 和 click 事件。轻击不可单击的元素不会触发任何事件。可单击的元素是指那些单击可产生默认操作的元素(如链接),或者那些已经被指定了 onclick 事件处理程序的元素。
    mousemove 事件也会触发 mouseover 和 mouseout 事件。
    两个手指放在屏幕上且页面随手指移动而滚动时会触发 mousewheel 和 scroll 事件。
  2. 无障碍性问题
    如果你的 Web 应用程序或网站要确保残疾人特别是那些使用屏幕阅读器的人都能访问,那么在使用鼠标事件时就要格外小心。前面提到过,可以通过键盘上的回车键来触发 click 事件,但其他鼠标事件却无法通过键盘来触发。为此,我们不建议使用 click 之外的其他鼠标事件来展示功能或引发代码执行。因为这样会给盲人或视障用户造成极大不便。以下是在使用鼠标事件时应当注意的几个易访问性问题。
    使用 click 事件执行代码。有人指出通过 onmousedown 执行代码会让人觉得速度更快,对视力正常的人来说这是没错的。但是,在屏幕阅读器中,由于无法触发 mousedown 事件,结果就会造成代码无法执行。
    不要使用 onmouseover 向用户显示新的选项。原因同上,屏幕阅读器无法触发这个事件。如果确实非要通过这种方式来显示新选项,可以考虑添加显示相同信息的键盘快捷方式。
    不要使用 dblclick 执行重要的操作。键盘无法触发这个事件。
    遵照以上提示可以极大地提升残疾人在访问你的 Web 应用程序或网站时的易访问性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值