在 JavaScript 中,event 对象由事件自动创建,记录了当前事件的状态,如事件发生的源节点、键盘按键的响应状态、鼠标指针的移动位置、鼠标按键的响应状态等信息。event 对象的属性提供了有关事件的细节,其方法可以控制事件的传播。
2 级 DOM Events 规范定义了一个标准的事件模型,它被除了 IE 怪异模式以外的所有现代浏览器所实现,而 IE 定义了专用的、不兼容的模型。简单比较两种事件模型如下:
下面列出了 2 级 DOM 事件标准定义的 event 对象属性,如下图所示。注意,这些属性都是只读属性。
属性 | 说明 |
---|---|
bubbles | 返回布尔值,指示事件是否是冒泡事件类型。如果事件时冒泡类型,则返回 true;否则返回 false |
cancelable | 返回布尔值,指示事件是否可以取消的默认动作。如果使用 preventDefault() 方法可以取消与事件关联的默认动作,则返回值为 true;否则为 false |
currentTarget | 返回触发事件的当前节点,即当前处理该事件的元素、文档或接口。在捕获和冒泡阶段,该属性时非常有用的,因为在这两个阶段,它不同于 target 属性 |
eventPhase | 返回事件传播的当前阶段,包括捕获阶段(1)、目标事件阶段(2)和冒泡阶段(3) |
target | 返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口 |
timeStamp | 返回事件生成的日期和时间 |
type | 返回当前 event 对象表示的事件的名称。如“submit”、“load”或“click” |
下面列出了 2 级 DOM 事件标准定义的 event 对象方法,如下表所示。IE 事件模型不支持这些方法。
方法 | 声明 |
---|---|
initEvent() | 初始化新创建的 event 对象的属性 |
preventDefault() | 通知浏览器不要执行与事件关联的默认动作 |
stopPropagation() | 终止事件在传播过程的捕获、目标处理或冒泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理函数将被调用,但事件不再被分派到其他节点 |
上表是 Event 类型提供的基本属性,各个事件子模块也都定义了专用属性和方法。例如,UIEvent 提供了 view(发生事件的 window 对象)和 detail(事件的详细信息)属性;而 MouseEvent 除了拥有 Event 和 UIEvent 属性和方法外,也定义了更多实用属性。
IE 7 及其早期版本,,以及 IE 怪异模式不支持标准的 DOM 事件模型,并且 IE 的 event 对象定义了一组完全不同的属性,如下表所示:
属性 | 描述 |
---|---|
cancelBubble | 如果想在事件处理函数中阻止事件传播到上级包含对象,必须把该属性设为 true |
fromElement | 对于 mouseover 和 mouseout 事件,fromElement 引用移出鼠标的元素 |
keyCode | 对于 keypress 事件,该属性声明了被敲击的键生成的 Unicode 字符码。对于 keydown 和 keyup 事件,它指定了被敲击的键的虚拟键盘码。虚拟键盘码可能和使用的键盘的布局相关 |
offsetX、offsetY | 发生事件的地点在事件源元素的坐标系统中的 x 坐标和 y 坐标 |
returnValue | 如果设置了该属性,它的值比事件处理函数的返回值优先级高。把这个属性设置为 false,可以取消事件发生的源元素的默认动作 |
srcElement | 对于生成事件的 window 对象、document 对象或 element 对象的引用 |
toElement | 对于 mouseover 和 mouseout 事件,该属性引用移入鼠标的元素 |
x、y | 事件发生的位置的 x 坐标和 y 坐标,它们相对于用 CSS 定位的最内层包含元素 |
IE 事件模型并没有为不同的事件定义继承类型,因此所有和任何事件的的类型相关的属性都在上面列表中。
为了兼容 IE 和 DOM 两种事件模型,可以使用下面表达式进行兼容。
var event = event || window.event; //兼容不同模型的event对象
上面代码右侧是一个选择运算表达式,如果事件处理函数存在 event 实参,则使用 event 形参来传递事件信息;如果不存在 event 参数,则调用 window 对象的 event 属性来获取事件信息。把上面表达式放在事件处理函数中即可进行兼容。
在以事件驱动为核心的设计模型中,一次只能处理一个事件,由于从来不会并发两个事件,因此使用全局变量来存储事件信息是一种比较安全的方法。
下面示例演示了如何禁止超链接默认的跳转行为。
<a href="https://www.baidu.com/" id="a1">禁止超链接跳转</a>
<script>
document.getElementById("a1").onclick = function(e) {
e = e || window.event; //兼容事件对象
var target = e.target || e.srcElement; //兼容事件目标元素
if (target.nodeName !== 'A') { //仅针对超链接起作用
return;
}
if (typeof e.preventDefault === 'function') { //兼容DOM模型
e.preventDefault(); //禁止默认行为
e.cancelBubble(); //禁止事件传播
} else { //兼容IE类型
e.returnValue = false; //禁止默认行为
e.cancelBubble = true; //禁止冒泡
}
};
</script>