深入理解 addEventListener
语法一: 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相关推荐
- addeventlistener事件第三个参数_简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序...
这篇文章主要介绍了javaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序整理总结的相关资料 (一)事件绑定的几种方式 javascript给DOM绑定事件处理函数总的来说有2种方式:在htm ...
- javascript中的事件冒泡、事件捕获和事件执行顺序
谈起JavaScript的 事件,事件冒泡.事件捕获.阻止默认事件这三个话题,无论是面试还是在平时的工作中,都很难避免. DOM事件标准定义了两种事件流,这两种事件流有着显著的不同并且可能对你的应用有 ...
- JavaScript 中的事件设计
1. 事件绑定的几种方式 主要介绍一下 最常用的事件设计 其他就稍微带过. 直接在代码里面添加onclick指定函数名字. B) 在JS代码中通过dom元素的onclick等属性 这种做法this表 ...
- 简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序
JavaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序 这篇文章主要介绍了javaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序整理总结的相关资料 (一)事件绑定的几种方式 jav ...
- document.addEventListener理解
document.addEventListener("事件名称", 函数, false); function 某函数(event){ // 方法执行 } addEventList ...
- 对javscript中Object.defineProperty的理解
自己在使用vue的过程中经常会用到听到数据双向绑定这个词,而且我们还可以直接通过调用this.msg(this表示vue实例),来获取data上的数据,以前一直不太明白为什么可以这样获取,直到有一 ...
- 后处理程序文件大小的变量_【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?...
关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 2020,实「鼠」不易 2021,「牛」转乾坤 风劲潮涌当扬帆,任重道远须奋蹄! 一.前言 2020.12.23 立 ...
- 什么是闭包,我的理解
首先,我觉得,一个概念,如果不理解也不影响使用的话,那么,就没必要去理解它.去学习它.闭包就是这样一个概念,你不理解它也能很好的用它.俺这两年写as3程序,是天天在和它打交道,甚至有过一个functi ...
- react 日期怎么格式化_手写React的Fiber架构,深入理解其原理
熟悉React的朋友都知道,React支持jsx语法,我们可以直接将HTML代码写到JS中间,然后渲染到页面上,我们写的HTML如果有更新的话,React还有虚拟DOM的对比,只更新变化的部分,而不重 ...
最新文章
- secureCRT自动断开的解决方法
- ruby中DBI连接MySQL数据库步骤详解
- 数列分段pascal程序
- php返回上一层的函数6,[PHP]实用函数6第1/2页
- 收藏 | LSTM模型结构的可视化
- java 生成素数_java – 素数生成器逻辑
- java毕业设计——基于java+jsp+Tomcat的电子书下载系统设计与实现(毕业论文+程序源码)——电子书下载系统
- 数据库系统概论--课后习题
- 天津大学计算机应用基础考试,天津大学2020秋季《计算机应用基础》在线考核试题B...
- 麦克风声源定位原理_关于基于麦克风阵列的声源被动定位系统的设计
- jsp遍历List map
- 图片怎么去水印?大神教你3个免费去水印方法
- 无监督低照度图像增强网络ZeroDCE和SCI介绍
- VUE2.0全局方法注册
- javascript与python性能对比-lua与python性能测试比较
- PTGUI 720 制作全景图
- IOS开发工具介绍之Xcode开发工具使用
- webpack实现es6转换为es5
- 从一位老工程师的心里话开始谈起IT行业职
- 使用PicGo+阿里云OSS实现md文档图片上传
热门文章
- 简单时间计算(顺序-选择)
- vso downloader怎么安装?安装步骤+视频下载方法【图】
- GoLang爬取今日热榜
- 《星际争霸2》引擎技术解析(转)
- 你见过代码里面的“龟派气功”吗?
- ios 微信小程序 chooseImage 相机拍照跳转页面崩溃
- CSS div footer,网站Footer导航完美自动固定在底部div+css
- ppt如何旋转流程图_如何利用PPT中的 SmartArt 轻松制作流程图,搞定 Office 多图排版...
- 联发科MT6639与Wi-Fi 7兼容吗?
- 银行卡文字识别技术在项目里如何应用