Javascript 事件对象

什么是事件对象

  • 概念:
    在触发 DOM 上的某个事件时会产生一个事件对象 event,这个对象中包含着所有与事件相关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。目前所有浏览器都支持 event 对象,只是支持方式不同。
  • 组成:
  1. DOM 中的事件对象
  2. IE 中的事件对象

DOM 中的事件对象

兼容 DOM 的浏览器都会将一个 event 对象传入事件处理程序中。无论是 DOM0 级还是 DOM2 级。

1
2
3
4
5
6
7
var btn = document.getElementById('myBtn');
btn.onclick = function (event) {
alert(event.type);
};
btn.addEventListener('click', function (event) {
alert(event.type);
},false)

event 对象:

属性/方法 类型 读/写 说明
bubbles Boolean 只读 事件是否冒泡
cancelable Boolean 只读 是否可以取消事件的默认行为
currentTarget Boolean 只读 事件程序当前正在处理事件的哪个元素
defaultPrevented Boolean 只读 true 表示已经调用了 preventeDefault()
detail Integer 只读 与事件相关的详细信息
eventPhase Integer 只读 调用事件处理程序的阶段:1捕获阶段,2‘处于目标’,3冒泡阶段
preventeDefault Function 只读 取消事件默认行为,cancelabletrue 则可以使用该方法
stopImmediatePropagation() Function 只读 取消事件的进一步冒泡或捕获,同时阻止任何事件处理程序被调用
stopPropagation() Function 只读 取消事件的进一步冒泡或者捕获,bubblestrue 则可以使用这个方法
target Element 只读 事件目标
trusted Boolean 只读 true 表示事件是浏览器生成的,false 则表示是事件是由开发人员通过 Javascript 创建的
type String 只读 被触发的事件类型
view AbstractView 只读 与事件关联的抽象视图。等同于发生事件的 window 对象

在事件处理程序内部 this 始终等于 currentTarget 的值,而 target 则只包含事件的实际目标。
如果事件处理程序存在于元素的父级节点中,那么这些值是不相同的。

1
2
3
4
5
6
document.body.onclick = function (event) {
alert(event.currentTarget === document.body);// true => document.body 为 实际注册事件的元素节点
alert(this === document.body);// true
alert(event.=target === document.getElementById('myBtn'));// false => document.getElementById('myBtn') 目标元素
}
// click 事件的触发是因为点击按钮后冒泡到 ducument.body 后事件得到了处理

在需要通过一个元素处理多个事件时,可以使用 type 属性区分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var btn = document.getElementById('myBtn');
var handler = function (event) {
switch (event.type) {
case 'click':
alert('Clicked');
break;
case 'mouseover':
alert('Mouseover');
break;
case 'mouseout':
alert('Mouseout');
break;
default:
alert('No Event');
}
}

阻止特定事件的默认行为可以使用 preventeDefault() 方法

1
2
3
4
var link = document.getElementById('link');
link.onclick = function (event) {
event.preventeDefault();
}

阻止事件在 DOM 层中继续传播(事件的进一步捕获或冒泡),可以使用 stopPropagation()

1
2
3
4
5
6
7
8
9
var btn = document.getElementById('myBtn');
btn.onclick = function (event) {
alert('Clicked');
event.stopPropagation();// 阻止事件进一步传播
}
document.body.onclick = function (event) {
alert('Body Clicked');
}
// 点击按钮后,只会弹出一个警告框。因为 click 事件不会传播到 document.body 上。

加下来考验综合能力的时候开始了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var btn = document.getElementById('myBtn');

// 直接在目标元素上添加的事件处理程序,故弹出 ‘处于目标’ 状态
btn.onclick = function (event) {
alert(event.eventPhase); // 2‘处于目标’
};

// 使用 DOM2 级方法添加的事件处理程序,并设置第三参数为 true 就表明 事件会在事件流的捕获阶段被执行
document.body.addEventListener('click', function (event) {
alert(event.eventPhase);// 1‘捕获阶段’
}, true);

// 使用 DOM0 级方法添加的事件处理程序会在事件流的冒泡阶段被执行 还有一个比较靠谱的解释:点击的目标节点是 btn ,所以触发 body 上的事件处理程序就应该是经过事件的进一步传播(冒泡)才能完成的。
document.body.onclick = function (event) {
alert(event.eventPhase); // 3‘冒泡阶段’
};
⚠️注意:只有在事件处理程序执行期间,event 对象才会存在。一旦事件处理程序执行完毕,event 对象就会被销毁。

IE 中的事件处理对象

IE 中的 event 对象的方式取决于指定事件处理程序的方法。

使用 DOM0 级方法的话,event 作为 window 的 一个属性存在。

1
2
3
4
5
var btn = document.getElementById('myBtn');
btn.onclick = function () {
var event = window.event;
alert(event.type);// click
}

使用 DOM2 级方法的话,event 作为参数被传入事件处理程序函数中。

1
2
3
4
var btn = document.getElementById('myBtn');
btn.attachEvent('onclick', function (event) {
alert(event.type);// click
});

event 对象

属性/方法 类型 读/写 说明
cancelBubble Boolean 只读 默认值 false,设置 true 可以取消事件冒泡(同 stopPropagation()
returnValue Boolean 只读 默认值 true,设置 false 取消事件的默认行为(同 preventeDefault()
srcElement Boolean 只读 事件的目标(同 target
type Boolean 只读 被触发的事件类型

因为事件处理程序的作用域是根据指定它的方式来确定的,所以 this 并不是总是指向事件目标的。推荐使用 event.srcElement 比较保险。

1
2
3
4
5
6
7
8
9
10
11
12
var btn = document.getElementById('myBtn');

// DOM0 级,this 指向事件目标
btn.onclick = function () {
var event = window.event;
alert(window.event.srcElement === this);// true
}

// IE DOM2 级,this 指向 window
btn.attachEvent('onclick', function (event) {
alert(event.srcElement === this);// false
});