addEventListener

之前分配处理程序的方式的根本问题是 —— 我们不能为一个事件分配多个处理程序。

例如,在我们点击了一个按钮时,我们代码中的一部分想要高亮显示这个按钮,另一部分则想要显示一条消息。

我们想为此事件分配两个处理程序。但是,只有一个会生效。

ele.onclick = function() { alert(1); }
// ...
ele.onclick = function() { alert(2); } // 替换了前一个处理程序

Web 标准的开发者很早就了解到了这一点,并提出了一种使用 addEventListenerremoveEventListener 来管理处理程序的替代方法。它们没有这样的问题。

  • 它允许给一个事件注册多个 listener。

  • 它提供了一种更精细的手段控制 listener 的触发阶段。(即可以选择捕获或者冒泡)。

  • 它对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。

添加处理程序的语法:

element.addEventListener(event, handler[, options]);

event: 事件名,例如:"click"

handler: 处理程序。

options: 具有以下属性的附加可选对象:

capture:事件处理的阶段(捕获/冒泡)

要移除处理程序,可以使用 removeEventListener

element.removeEventListener(event, handler[, options]);
//要移除处理程序,我们需要传入与分配的函数完全相同的函数。
//参数信息必须一一对应

// 以下方式不起作用:

elem.addEventListener( "click" , () => alert('Thanks!'));
// ....
elem.removeEventListener( "click", () => alert('Thanks!'));

下面是正确方法:

function handler() {
  alert( 'Thanks!' );
}

input.addEventListener("click", handler);
// ....
input.removeEventListener("click", handler);

IE8 以下兼容问题

  • target.attachEvent(type, listener);
  • target.detachEvent(type,listener);
/**
 * 兼容IE8和标准浏览器
 * el 绑定元素
 * type 事件类型,IE8要加on
 * func 执行方法
 **/
function myAddEventListener(el, type, func) {
    // attachEvent 是IE 专有的方法
    if (el.attachEvent) {
        el.attachEvent("on" + type, func);
    } else {
        el.addEventListener(type, func);
    }
}

事件冒泡和捕获

当一个事件发生在具有父元素的元素上时,现代浏览器运行两个不同的阶段: 捕获阶段冒泡阶段

在捕获阶段:

浏览器检查元素的最外层祖先<html>,是否在捕获阶段中注册了onclick事件,如果是,则运行它。
然后,它检查<html>中点击元素的下一个祖先元素,并执行相同的操作,然后是点击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。

冒泡阶段:

浏览器检查实际点击的元素是否在冒泡阶段中注册了onclick事件,如果是,则运行它
然后检查下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达<html>元素。


在现代浏览器中,默认情况下,所有事件处理程序都在冒泡阶段进行注册。

注解: 如上所述,默认情况下,所有事件处理程序都是在冒泡阶段注册的,这在大多数情况下更有意义。如果真的想在捕获阶段注册一个事件,那么可以通过使用addEventListener()注册您的处理程序,并将可选的第三个属性设置为true。

文档更新时间: 2021-05-19 10:01   作者:张老师