这是我参与更文挑战的第27天,活动详情查看:更文挑战
开始之前我们来重新定义一下 EventUtil:
const EventUtil = {
addHandler: () => {
// 同上的代码
},
getEvent: (e) => {
return e ? e : window.event;
},
getTarget: (e) => {
return e.target || src.element;
},
preventDefault: (e) => {
if(e.preventDefault) {
e.preventDefault();
} else {
e.returnValues = false;
}
},
removeHandler: () => {
// 同上的代码
},
stopPropagation: () => {
if(e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
},
}
我们为 EventUtil 新增了 4 个新方法。
- getEvent: 返回对event对象的引用。
- getTarget: 返回事件的目标。
- preventDefault: 取消事件的默认行为。
- stopPropagation: 阻止事件流。
2.页面坐标位置
通过客户区坐标能够知道鼠标是在视口中什么位置发生的,而页面坐标通过事件对象的 pageX 和 pageY 属性,能告诉你事件是在页面中的什么位置发生的。这个位置是从页面本身的左边和顶边计算。
以下代码可以取得鼠标事件在页面中的坐标:
const div = document.getElementById('myDiv');
EventUtil.addHandler(div, 'click', (e) => {
e = EventUtil.getEvent(e);
alert(`page coordinates: ${e.pageX}, ${e.pageY}`);
});
在页面没有滚动的情况下, pageX 和 pageY 的值与 clientX 和 clientY 的值相等。
3.屏幕坐标位置
鼠标事件发生时,不仅会有相对于浏览器窗口的位置,还有一个相对于整个电脑屏幕的位置。而通过 screenX 和 screenY 属性就可以确定鼠标事件发生时鼠标相对于整个屏幕的坐标信息。
以下代码可以取得鼠标事件在屏幕中的坐标:
const div = document.getElementById('myDiv');
EventUtil.addHandler(div, 'click', (e) => {
e = EventUtil.getEvent(e);
alert(`screen coordinates: ${e.screenX}, ${e.screenY}`);
});
4.修改键
虽然鼠标事件需要鼠标来进行触发,但键盘上的某些键也可以影响到鼠标事件的操作。这些键叫做修改键。它们是 Shitf 、 Ctrl 、 Alt 和 Meta ( windows 系统是 win 键, mac 系统是 cmd 键),它们经常用来修改鼠标事件的行为。 DOM 为此规定了 4 个属性,表示这些修改键的状态: shiftKey 、 ctrlKey 、 altKey 和 metaKey 。这些属性都是以 boolean 类型来表示是否按下了修改件。
看看下面的例子:
const div = document.getElementById('myDiv');
EventUtil.addHandler(div, 'click', (e) => {
e = EventUtil.getEvent(e);
let keys = new Array();
if(e.shiftKey) {
keys.push('shiftKey');
}
if(e.ctrlKey) {
keys.push('ctrlKey');
}
if(e.altKey) {
keys.push('altKey');
}
if(e.metaKey) {
keys.push('metaKey');
}
alert(`keys === ${keys.join(',')}`);
});
这个例子可以获取到鼠标事件触发时,是否有修改键进行了操作,并在窗口提示给用户。
5.相关元素
在发生 mouseover 和 mouseout 事件时,会有成对的元素出现。我们需要在一个元素移动到另一个元素的相应位置才会触发这两个事件。而成对出现的这两个元素称为相关元素。
<!DOCTYPE html>
<html>
<head>
<title>相关元素</title>
</head>
<body>
<div id="myDiv" style="background-color: red; height: 100px; width: 100px;"></div>
</body>
</html>
在这个例子上,如果我们把鼠标从 div 元素上移开,那么就会在 div 元素上触发 mouseout 事件,相关元素就是 body 元素。与此同时 body 上会触发 mouseover 事件,而相关元素就是 div 。
DOM 通过 event 对象的 relatedTarget 属性提供了相关元素的信息。这个属性对于鼠标事件中,只有上述两个事件才有值,其余事件都是 null 。现有浏览器都支持这两个属性值。
此时我们的 EventUtil 又可以新增一个功能。
const EventUtil = {
// ...
getRelatedTarget: (e) => {
return e.relatedTarget || null;
},
}
使用方式如下:
const div = document.getElementById('myDiv');
EventUtil.addHandler(div, 'mouseout', (e) => {
e = EventUtil.getEvent(e);
const target = EventUtil.getTarget(e);
const relatedTarget = EventUtil.getRelatedTarget(e);
alert(`moused out of ${target.tagName} to ${relatedTarget.tagName}`);
});
mouseout 的时候展示触发元素以及相关元素的标签名称。