EventTarget是一个由可以接收事件的对象实现的接口,并且可以为它们创建侦听器。
DOM的事件操作,监听和触发,都定义在EventTarget接口,所有的节点对象都部署了这个接口,其他一些需要事件通信的浏览器内置对象,XMLHttpRequest,AudioNode,AudioContext也部署了这个接口
事件处理程序(addEventListener)
addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素 Element,Document和Window或者任何其他支持事件的对象 (比如 XMLHttpRequest)。
addEventListener()的工作原理是将实现EventListener的函数或对象添加到调用它的EventTarget上的指定事件类型的事件侦听器列表中。
格式为:
target.addEventListener(type, listener, useCapture);
type:
事件触发类型,如click,keypress等等
listener:
事件处理函数,当所监听的事件类型触发时,会接收到一个事件通知(实现了 Event 接口的对象)对象。 listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数。
useCapture:
Boolean,在DOM树中,注册了listener的元素, 是否要先于它下面的EventTarget,调用该listener。 当useCapture(设为true) 时,沿着DOM树向上冒泡的事件,不会触发listener。当一个元素嵌套了另一个元素,并且两个元素都对同一事件注册了一个处理函数时,所发生的事件冒泡和事件捕获是两种不同的事件传播方式。事件传播模式决定了元素以哪个顺序接收事件。 useCapture 默认为 false 。
优点:
1.它允许给一个事件注册多个监听器。 特别是在使用AJAX库,JavaScript模块,或其他需要第三方库/插件的代码。
2.它提供了一种更精细的手段控制 listener 的触发阶段。(即可以选择捕获或者冒泡)。
3.它对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。
示例1:
var flag = false;
btn.addEventListener('click',function(){
senction.style.backgroundColor = flag?'#ddd':'#bbb'
},false);
效果图如下图所示:
示例二:
<table id="outside">
<tr><td id="t1">one</td></tr>
<tr><td id="t2">two</td></tr>
</table>
// 改变t2值的函数
function modifyText(new_text) {
var t2 = document.getElementById("t2");
t2.firstChild.nodeValue = new_text;
}
// 为table对象添加事件监听器
var el = document.getElementById("outside");
el.addEventListener("click", function(){modifyText("four")}, false);
请注意,侦听器是一个匿名函数,它封装了代码,然后代码可以将参数发送到modifyText()函数,该函数负责实际响应事件。
this指向:
当使用 addEventListener() 为一个元素注册事件的时候,句柄里的 this 值是该元素的引用。其与传递给句柄的 event 参数的 currentTarget 属性的值一样。
如果一个事件的属性( 例如. onClick)是指定在一个HTML的元素上的,则这个属性中的JavaScript语句实际上会被包裹在一个处理函数中,在这个处理函数中使用this的效果和使用addEventListener来绑定事件的效果是一样的; this的出现代表了元素的引用。注意到在一个函数里this调用的的效果和标准规则里面是一样的。
比如下面的例子:
<table id="t" onclick="modifyText();">
这时modifyText()中的this 的值会变成全局 (window) 对象的引用(在严格模式中为 undefined)。
既然我们添加了监听器,那么我们怎么去解除绑定呢?
removeEventListener
删除使用 EventTarget.addEventListener() 方法添加的事件。使用事件类型,事件侦听器函数本身,以及可能影响匹配过程的各种可选择的选项的组合来标识要删除的事件侦听器。
格式为:
target.removeEventListener(type, listener[, useCapture]);
type
一个字符串,表示需要移除的事件类型,如 “click”。
listener
需要从目标事件移除的 EventListener 函数。
useCapture 可选
指定需要移除的 EventListener 函数是否为捕获监听器。如果无此参数,默认值为 false。
如果同一个监听事件分别为“事件捕获”和“事件冒泡”注册了一次,这两次事件需要分别移除。两者不会互相干扰。移除捕获监听器不会影响非捕获版本的相同监听器,反之亦然。
示例一:
绑定了一个监听器。
element.addEventListener("mousedown", handleMouseDown, true);
现在思考下下面两个 removeEventListener()。
element.removeEventListener("mousedown", handleMouseDown, false); // 失败
element.removeEventListener("mousedown", handleMouseDown, true); // 成功
第一个调用失败是因为 useCapture 没有匹配. 第二个调用成功,是因为useCapture 匹配相同.
注:
一个 EventTarget 上的 EventListener 被移除之后,如果此事件正在执行,会立即停止。 EventListener 移除之后不能被触发,但可以重新绑定。
在EventTarget上使用任何未识别当前注册的EventListener 调用 removeEventListener() 不会起任何作用。
以下例子展示了添加与删除监听事件:
var body = document.querySelector('body'),
clickTarget = document.getElementById('click-target'),
mouseOverTarget = document.getElementById('mouse-over-target'),
toggle = false;
function makeBackgroundYellow() {
'use strict';
if (toggle) {
body.style.backgroundColor = 'white';
} else {
body.style.backgroundColor = 'yellow';
}
toggle = !toggle;
}
clickTarget.addEventListener('click',
makeBackgroundYellow,
false
);
mouseOverTarget.addEventListener('mouseover', function () {
'use strict';
clickTarget.removeEventListener('click',
makeBackgroundYellow,
false
);
});