mouseover 和 mouseout 事件而言,还存在与事件相关的其他元素。这两个事件都涉及从一个元素的边界之内把光标移到另一个元素的边界之内。对 mouseover 事件来说,事件的主要目标是获得
光标的元素,相关元素是失去光标的元素。类似地,对 mouseout 事件来说,事件的主要目标是失去光标的元素,而相关元素是获得光标的元素。来看下面的例子:
<html>
<head>
<title>Related Elements Example</title>
</head>
<body>
<div id="myDiv"
style="background-color:red;height:100px;width:100px;"></div>
</body>
</html>
这个页面中只包含一个
元素。如果光标开始在
元素上,然后从它上面移出,则
元素上会触发 mouseout 事件,相关元素为元素。与此同时,元素上会触发 mouseover事件,相关元素是
元素。
DOM通过 event 对象的 relatedTarget 属性提供了相关元素的信息。这个属性只有在 mouseover和 mouseout 事件发生时才包含值,其他所有事件的这个属性的值都是 null。IE8 及更早版本不支持relatedTarget 属性,但提供了其他的可以访问到相关元素的属性。在 mouseover 事件触发时,IE会提供 fromElement 属性,其中包含相关元素。而在 mouseout 事件触发时,IE 会提供 toElement属性,其中包含相关元素。(IE9 支持所有这些属性。)因此,可以在 EventUtil 中增加一个通用的获取相关属性的方法:
DOM通过 event 对象的 relatedTarget 属性提供了相关元素的信息。这个属性只有在 mouseover和 mouseout 事件发生时才包含值,其他所有事件的这个属性的值都是 null。IE8 及更早版本不支持relatedTarget 属性,但提供了其他的可以访问到相关元素的属性。在 mouseover 事件触发时,IE会提供 fromElement 属性,其中包含相关元素。而在 mouseout 事件触发时,IE 会提供 toElement属性,其中包含相关元素。(IE9 支持所有这些属性。)因此,可以在 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;
}
},
// 其他代码
};
与前面介绍的其他跨浏览器方法一样,这个方法同样使用特性检测来确定要返回哪个值。可以像下面这样使用 EventUtil.getRelatedTarget()方法:
div.addEventListener("mouseout", (event) => {
let target = event.target;
let relatedTarget = EventUtil.getRelatedTarget(event);
console.log(
`Moused out of ${target.tagName} to ${relatedTarget.tagName}`);
});
这个例子在
元素上注册了 mouseout 事件处理程序。当事件触发时,就会打印出一条消息说明鼠标从哪个元素移出,移到了哪个元素上。
鼠标按键
只有在元素上单击鼠标主键(或按下键盘上的回车键)时 click 事件才会触发,因此按键信息并不是必需的。对 mousedown 和 mouseup 事件来说,event 对象上会有一个 button 属性,表示按下或释放的是哪个按键。DOM 为这个 button 属性定义了 3 个值:0 表示鼠标主键、1 表示鼠标中键(通常也是滚轮键)、2 表示鼠标副键。按照惯例,鼠标主键通常是左边的按键,副键通常是右边的按键。
IE8 及更早版本也提供了 button 属性,但这个属性的值与前面说的完全不同:
0,表示没有按下任何键;
1,表示按下鼠标主键;
2,表示按下鼠标副键;
3,表示同时按下鼠标主键、副键;
4,表示按下鼠标中键;
5,表示同时按下鼠标主键和中键;
6,表示同时按下鼠标副键和中键;
7,表示同时按下 3 个键。
很显然,DOM 定义的 button 属性比 IE 这一套更简单也更有用,毕竟同时按多个鼠标键的情况很少见。为此,实践中基本上都以 DOM 的 button 属性为准,这是因为除 IE8 及更早版本外的所有主流浏览器都原生支持。主、中、副键的定义非常明确,而 IE 定义的其他情形都可以翻译为按下其中某个键,而且优先翻译为主键。比如,IE 返回 5 或 7 时,就会对应到 DOM 的 0。
额外事件信息
DOM2 Events 规范在 event 对象上提供了 detail 属性,以给出关于事件的更多信息。对鼠标事件来说,detail 包含一个数值,表示在给定位置上发生了多少次单击。单击相当于在同一个像素上发
生一次 mousedown 紧跟一次 mouseup。detail 的值从 1 开始,每次单击会加 1。如果鼠标在 mousedown和 mouseup 之间移动了,则 detail 会重置为 0。
IE 还为每个鼠标事件提供了以下额外信息:
鼠标按键
只有在元素上单击鼠标主键(或按下键盘上的回车键)时 click 事件才会触发,因此按键信息并不是必需的。对 mousedown 和 mouseup 事件来说,event 对象上会有一个 button 属性,表示按下或释放的是哪个按键。DOM 为这个 button 属性定义了 3 个值:0 表示鼠标主键、1 表示鼠标中键(通常也是滚轮键)、2 表示鼠标副键。按照惯例,鼠标主键通常是左边的按键,副键通常是右边的按键。
IE8 及更早版本也提供了 button 属性,但这个属性的值与前面说的完全不同:
0,表示没有按下任何键;
1,表示按下鼠标主键;
2,表示按下鼠标副键;
3,表示同时按下鼠标主键、副键;
4,表示按下鼠标中键;
5,表示同时按下鼠标主键和中键;
6,表示同时按下鼠标副键和中键;
7,表示同时按下 3 个键。
很显然,DOM 定义的 button 属性比 IE 这一套更简单也更有用,毕竟同时按多个鼠标键的情况很少见。为此,实践中基本上都以 DOM 的 button 属性为准,这是因为除 IE8 及更早版本外的所有主流浏览器都原生支持。主、中、副键的定义非常明确,而 IE 定义的其他情形都可以翻译为按下其中某个键,而且优先翻译为主键。比如,IE 返回 5 或 7 时,就会对应到 DOM 的 0。
额外事件信息
DOM2 Events 规范在 event 对象上提供了 detail 属性,以给出关于事件的更多信息。对鼠标事件来说,detail 包含一个数值,表示在给定位置上发生了多少次单击。单击相当于在同一个像素上发
生一次 mousedown 紧跟一次 mouseup。detail 的值从 1 开始,每次单击会加 1。如果鼠标在 mousedown和 mouseup 之间移动了,则 detail 会重置为 0。
IE 还为每个鼠标事件提供了以下额外信息:
ctrlLeft,布尔值,表示是否按下了左 Ctrl 键(如果 ctrlLeft 是 true,那么 ctrlKey 也是true);
offsetX,光标相对于目标元素边界的 x 坐标;
offsetY,光标相对于目标元素边界的 y 坐标;
shiftLeft,布尔值,表示是否按下了左 Shift 键(如果 shiftLeft 是 true,那么 shiftKey也是 true)。
这些属性的作用有限,这是因为只有 IE 支持。而且,它们提供的信息要么没必要,要么可以通过其他方式计算。