语法一: target.addEventListener(type, listener, useCapture)

参数一:事件类型,比如 click、mouseenter、drag等。

参数二:事件被触发时的回调函数。

参数三:useCapture: 默认值为false,表示在冒泡阶段处理事件。 如果为true,则在捕获阶段处理事件。

语法二:target.addEventListener(type, listener, options)

options对象:

useCapture: 默认值为false,事件将在冒泡阶段触发。 如果为true,事件将在捕获阶段触发。

once: 表示 listener 在添加之后是否最多只调用一次。如果是 true, listener 会在其被调用之后自动移除。

passive: 设置为 true 时,表示 listener 永远不会调用 preventDefault()。使用 passive 可改善的滚屏性能。(根据标准,passive的值默认为false,最新的chrome和firefox已经默认将passive设置为true。)

为什么会有 passive 的出现??-- addEventListener使用 passive 可改善的滚屏性能

移动端的一些事件比如 touchstart 、 touchmove 、 touchend 、 touchcancel 等,如果在这些事件中阻止默认行为,页面会被禁止滚动或缩放。

而浏览器无法事先知道一个监听器是否会禁止默认行为,要等监听器执行之后,才会去执行默认行为。而监听器的执行是要耗时的,如果在 event.preventDefault() 之前耗时了 2秒 ,这样就会导致页面卡顿。

为了提升此种场景下的滚动体验,我们需要有一个参数来告诉浏览器,我的事件监听器中不会有 event.preventDefault() ,你可以不用等监听器执行完毕,请尽情的滚动吧。所以有了 passive 属性。为了兼容之前的 useCapture ,把最后一个参数改成了一个对象 options。

所以在绑定移动端相关的 touch 和滚动事件时,尽可能使用 { passive: true } 来提升性能和体验,避免出现页面卡顿。

然而,不是所有的浏览器都支持 passive 特性,不支持 passive 特性的浏览器会把最后一个参数当作 useCapture ,所以需要这段精妙的代码判断是否支持 passive 特性:

// Test via a getter in the options object to see
// if the passive property is accessed
var supportsPassive = false;
try {var opts = Object.defineProperty({}, 'passive', {get: function() {supportsPassive = true;}});window.addEventListener("test", null, opts);
} catch (e) {}// Use our detect's results.
// passive applied if supported, capture will be false either way.
elem.addEventListener('touchstart',fn,supportsPassive ? { passive: true } : false
);

通过 Object.defineProperty 设置一个 passive 的 get 访问器,添加一个 test 的事件,当浏览器支持的时候会调用 get 访问器,在 get 访问器中设置 supportsPassive。

在Angular框架中,Angular CDK 早已在 @angular/cdk/platform 模块提供了normalizePassiveListenerOptions({passive: true}) 供我们解决兼容性的问题,核心代码如下:

/*** @license* Copyright Google LLC All Rights Reserved.** Use of this source code is governed by an MIT-style license that can be* found in the LICENSE file at https://angular.io/license*//** Cached result of whether the user's browser supports passive event listeners. */
let supportsPassiveEvents: boolean;/*** Checks whether the user's browser supports passive event listeners.* See: https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md*/
export function supportsPassiveEventListeners(): boolean {if (supportsPassiveEvents == null && typeof window !== 'undefined') {try {window.addEventListener('test',null!,Object.defineProperty({}, 'passive', {get: () => (supportsPassiveEvents = true),}),);} finally {supportsPassiveEvents = supportsPassiveEvents || false;}}return supportsPassiveEvents;
}/*** Normalizes an `AddEventListener` object to something that can be passed* to `addEventListener` on any browser, no matter whether it supports the* `options` parameter.* @param options Object to be normalized.*/
export function normalizePassiveListenerOptions(options: AddEventListenerOptions,
): AddEventListenerOptions | boolean {return supportsPassiveEventListeners() ? options : !!options.capture;
}

添加绑定事件支持 passive 参数的相关Issue:https://github.com/angular/angular/issues/8866

深入理解 addEventListener相关推荐

  1. addeventlistener事件第三个参数_简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序...

    这篇文章主要介绍了javaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序整理总结的相关资料 (一)事件绑定的几种方式 javascript给DOM绑定事件处理函数总的来说有2种方式:在htm ...

  2. javascript中的事件冒泡、事件捕获和事件执行顺序

    谈起JavaScript的 事件,事件冒泡.事件捕获.阻止默认事件这三个话题,无论是面试还是在平时的工作中,都很难避免. DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有 ...

  3. JavaScript 中的事件设计

    1. 事件绑定的几种方式  主要介绍一下 最常用的事件设计 其他就稍微带过. 直接在代码里面添加onclick指定函数名字. B) 在JS代码中通过dom元素的onclick等属性 这种做法this表 ...

  4. 简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序

    JavaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序 这篇文章主要介绍了javaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序整理总结的相关资料 (一)事件绑定的几种方式 jav ...

  5. document.addEventListener理解

    document.addEventListener("事件名称", 函数, false); function 某函数(event){ //  方法执行 } addEventList ...

  6. 对javscript中Object.defineProperty的理解

      自己在使用vue的过程中经常会用到听到数据双向绑定这个词,而且我们还可以直接通过调用this.msg(this表示vue实例),来获取data上的数据,以前一直不太明白为什么可以这样获取,直到有一 ...

  7. 后处理程序文件大小的变量_【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?...

    关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 2020,实「鼠」不易 2021,「牛」转乾坤 风劲潮涌当扬帆,任重道远须奋蹄! 一.前言 2020.12.23 立 ...

  8. 什么是闭包,我的理解

    首先,我觉得,一个概念,如果不理解也不影响使用的话,那么,就没必要去理解它.去学习它.闭包就是这样一个概念,你不理解它也能很好的用它.俺这两年写as3程序,是天天在和它打交道,甚至有过一个functi ...

  9. react 日期怎么格式化_手写React的Fiber架构,深入理解其原理

    熟悉React的朋友都知道,React支持jsx语法,我们可以直接将HTML代码写到JS中间,然后渲染到页面上,我们写的HTML如果有更新的话,React还有虚拟DOM的对比,只更新变化的部分,而不重 ...

最新文章

  1. secureCRT自动断开的解决方法
  2. ruby中DBI连接MySQL数据库步骤详解
  3. 数列分段pascal程序
  4. php返回上一层的函数6,[PHP]实用函数6第1/2页
  5. 收藏 | LSTM模型结构的可视化
  6. java 生成素数_java – 素数生成器逻辑
  7. java毕业设计——基于java+jsp+Tomcat的电子书下载系统设计与实现(毕业论文+程序源码)——电子书下载系统
  8. 数据库系统概论--课后习题
  9. 天津大学计算机应用基础考试,天津大学2020秋季《计算机应用基础》在线考核试题B...
  10. 麦克风声源定位原理_关于基于麦克风阵列的声源被动定位系统的设计
  11. jsp遍历List map
  12. 图片怎么去水印?大神教你3个免费去水印方法
  13. 无监督低照度图像增强网络ZeroDCE和SCI介绍
  14. VUE2.0全局方法注册
  15. javascript与python性能对比-lua与python性能测试比较
  16. PTGUI 720 制作全景图
  17. IOS开发工具介绍之Xcode开发工具使用
  18. webpack实现es6转换为es5
  19. 从一位老工程师的心里话开始谈起IT行业职
  20. 使用PicGo+阿里云OSS实现md文档图片上传

热门文章

  1. 简单时间计算(顺序-选择)
  2. vso downloader怎么安装?安装步骤+视频下载方法【图】
  3. GoLang爬取今日热榜
  4. 《星际争霸2》引擎技术解析(转)
  5. 你见过代码里面的“龟派气功”吗?
  6. ios 微信小程序 chooseImage 相机拍照跳转页面崩溃
  7. CSS div footer,网站Footer导航完美自动固定在底部div+css
  8. ppt如何旋转流程图_如何利用PPT中的 SmartArt 轻松制作流程图,搞定 Office 多图排版...
  9. 联发科MT6639与Wi-Fi 7兼容吗?
  10. 银行卡文字识别技术在项目里如何应用