在触发 DOM 上的某个事件时,会产生一个事件对象(Event Object),这个对象中包含着所有与事件有关的属性和方法。该对象会作为第一个参数传递给监听函数。
type
:用于获取事件类型target
:获取事件目标stopPropagation()
:阻止事件冒泡preventDefault()
:阻止默认行为type
:用于获取事件类型srcElement
:获取事件目标cancelBubble
:阻止事件冒泡returnValue
:阻止事件默认行为兼容 DOM 的浏览器会将一个 event
对象传入到事件处理程序中。无论指定事件处理程序时使用什么方法(DOM0 级或 DOM2 级),都会传入 event
对象。
以这种方式提供 event
对象,可以让 HTML 特性事件处理程序与 JavaScript 函数执行相同的操作。event
对象包含与创建它的特定事件相关的属性和方法。触发的事件类型不一样。不过,所有事件都会有下表列出的成员。
属性/方法 | 类型 | 读/写 | 说明 |
---|---|---|---|
bubbles | Boolean | 只读 | 表明事件是否冒泡 |
cancelable | Boolean | 只读 | 表明是否可以取消事件的默认行为 |
currentTarget | Element | 只读 | 其事件处理程序当前正在处理事件的那个元素 |
defaultPrevented | Boolean | 只读 | 为 true 表示已经调用了 preventDefault() (DOM3 级事件中新增) |
detail | Integer | 只读 | 与事件相关的细节信息 |
eventPhase | Integer | 只读 | 调用事件处理程序的阶段:1 表示捕获阶段,2 表示“处于目标”,3 表示冒泡阶段 |
preventDefault() | Function | 只读 | 取消事件的默认行为。如果 cancelable 是 true ,则可以使用这个方法。 |
stopImmediatePropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3 级事件中新增) |
stopPropagation() | Function | 只读 | 取消事件的进一步捕获或冒泡。如果 bubbles 为 true ,则可以使用这个方法 |
target | Element | 只读 | 事件的目标 |
trusted | Boolean | 只读 | 为 true 表示事件是浏览器生成的。为 false 表示事件是由开发人员通过 JavaScript 创建的(DOM3 级事件中新增) |
type | String | 只读 | 被触发的事件的类型 |
view | AbstractView | 只读 | 与事件关联的抽象视图。等同于发生事件的 window 对象 |
在事件处理程序内部,对象 this
始终等于 currentTarget
的值,而 tartget
则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则 this
、currentTarget
和 tartget
包含相同的值。
// Examplevar btn = doocument.getElementById('myBtn');btn.onclick = function(event) {alert(event.currentTarget === this); // truealert(event.target === this); // true};
当单击这个例子中的按钮时,this
和 currentTarget
都等于 document.body
,因为事件处理程序是注册到这个元素上的。然而,target
元素却等于按钮元素,因为它是 click
事件真正的目标。由于按钮上并没有注册事件处理程序,结果 click
事件就冒泡到了 document.body
,在那里事件才得到了处理。
在需要通过一个函数处理多个事件时,可以使用 type
属性。例如:
var btn = document.getElementById('myBtn');var handler = function(event) {switch (event.type) {case 'click':alert('Clicked');break;case 'mouseover':event.target.style.backgroundColor = 'red';break;case 'mouseout':event.target.style.backgroundColor = '';break;}};btn.onclick = handler;btn.mouseover = handler;btn.mouseout = handler;
这个例子定义了一个名为 handler
的函数,用于处理 3 种事件:click
、mouseover
和mouseout
。当单击按钮时,会出现一个与前面例子中一样的警告框。当按钮移动到按钮上面时,背景颜色应该会变成红色,而当鼠标移动出按钮的范围时,背景颜色应该会恢复为默认值。这里通过检测 event.type
属性,让函数能够确定发生了什么事件,并执行相应的操作。
要阻止特定事件的默认行为,可以使用 preventDefault()
方法。例如,链接的默认行为就是在被单击时会导航到其 href
特性指定的 URL。如果你想阻止链接导航这一默认行为,那么通过链接的 onclick
事件处理程序可以取消它。
var link = document.getElementById('myLink');link.onclick = function(event) {// 阻止鼠标的默认行为event.preventDefault();};
只有 cancelable
属性设置为 true
的事件,才可以使用 preventDefault()
来取消其默认行为。
stopPropagation()
方法用于立即停止事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡。
function stopPropagation(e) {const event = e || window.event;event.stopPropagation ? event.stopPropagation() : (window.event.cancelBubbl = true);}
⚠️ 只有在事件处理程序执行期间,event 对象才会存在。一旦事件处理程序执行完成,event 对象就会被销毁。
虽然 DOM 和 IE 中的 event
对象不同,但基于它们之间的相似性依旧可以拿出跨浏览器的方案来。IE 中 event
对象的全部信息和方法 DOM 对象中都有,只不过实现方式不一样。不过,这种对应关系让实现两种事件模型之间的映射非常容易。可以对前面介绍的 EventUtil 对象加以增强,添加如下方法以求同存异。
const EventUtil = {addHandler: function(element, type, handler) {// 省略的代码},getEvent: function(event) {return event ? event : window.event;}getTarget: function(event) {return event.target || event.srcElement;}preventDefault: function(event) {if (event.preventDefault){event.preventDefault();} else {event.returnValue = false;}}removeHandler: function(element, type, handler) {// 省略的代码}stopPropagation: function(event) {if (event.stopPropagation) {event.stopPropagation;} else {event.cancelBubble = true;}}}
参考资料: