事件监听器

随堂测验:传递给 addEventListener() 的第三个参数的用途是什么?

如果您认为 addEventListener() 只接受两个参数,或者只是始终对 false 进行硬编码,并模糊地知道它与气泡有关,请不要感到尴尬。

可配置性更高的 addEventListener()

自 Web 诞生之初以来,addEventListener() 方法已经走过了漫长的道路,其新功能是通过该第三个参数的增强版配置的。方法定义最近发生的变化让开发者能够通过配置对象提供其他选项,同时在存在布尔值参数或未指定选项时保持向后兼容性。

我们很高兴地宣布,Chrome 55 在该配置对象中添加了对 once 选项的支持,以及 passive在 Chrome 51 中实现)和 capture 选项(在 Chrome 49 中实现)。例如:

element.addEventListener('click', myClickHandler, {
    once: true,
    passive: true,
    capture: true
});

您可以根据自己的使用场景灵活搭配使用这些选项。

自觉维持车内清洁的好处

以上就是使用新 once 选项的语法,但这能为您带来什么好处呢?简而言之,它可为您提供专门针对“一劳永逸”用例的事件监听器。

默认情况下,事件监听器会在首次调用后保留,这对于某些类型的事件(例如可多次点击的按钮)来说是理想的做法。不过,对于其他用途,事件监听器无需一直保留,如果您有一个只能执行一次的回调,则可能会导致不良行为。注重代码整洁的开发者一直可以选择使用 removeEventListener() 来明确清理代码,遵循以下模式:

element.addEventListener('click', function cb(event) {
    // ...one-time handling of the click event...
    event.currentTarget.removeEventListener(event.type, cb);
});

使用新 once 参数的等效代码更简洁,并且不会强制您跟踪事件名称(上例中的 event.type)或对回调函数的引用 (cb):

element.addEventListener('click', function(event) {
    // ...one-time handling of the click event...
}, {once: true});

通过销毁与回调函数关联的范围,清理事件处理脚本还可以提高内存效率,从而允许在该范围内捕获的任何变量进行垃圾回收。下面是一个这样的示例:

function setUpListeners() {
    var data = ['one', 'two', '...etc.'];

    window.addEventListener('load', function() {
    doSomethingWithSomeData(data);
    // data is now part of the callback's scope.
    });
}

默认情况下,load 事件监听器回调在运行完毕后仍会保留在作用域中,即使它永远不会再次使用也是如此。由于 data 变量在回调内使用,因此它也会保留在作用域内,并且永远不会被垃圾回收。不过,如果通过 once 参数移除回调,则函数本身以及通过其作用域保持活跃状态的所有内容都可能会成为垃圾回收的候选对象。

浏览器支持

Chrome 55 及更高版本、Firefox 50 及更高版本以及 Safari 的技术预览版 7 及更高版本once 选项提供原生支持

许多 JavaScript 界面库都提供了用于创建事件监听器的便捷方法,其中一些库还提供了用于定义一次性事件的快捷方式,其中最值得注意的是 jQuery 的 one() 方法Andrea Giammarchidom4中还提供了 polyfill。

谢谢

感谢 Ingvar Stepanyan 就本文中的示例代码提供反馈