Web:移动端阻止默认行为的小坑

博客 分享
0 312
优雅殿下
优雅殿下 2022-02-08 21:55:08
悬赏:0 积分 收藏

Web:移动端阻止默认行为的小坑

移动端 web 开发中,使用 addEventListener 阻止了 touchstart 事件的默认行为却发现没有生效。其实是 addEventListener 中参数的坑

问题

移动端 web 开发中,使用 addEventListener 阻止了 touchstart 事件的默认行为却发现没有生效

描述

再移动端 web 开发中,我们一般会用 addEventListener 给 document 节点的 touchstart 事件设置 preventDefault() 方法以达到禁用事件默认行为的目的,但有时候会发现在 chrome 移动端模拟器或者手机浏览器上事件的默认行为并没有成功禁用。

document.addEventListener("touchstart", function (ev) {    ev = ev || event;    ev.preventDefault();});

原因

首先来看下 MDN 中 addEventListener() 方法的描述:

EventTarget.addEventListener()

EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素 Element,DocumentWindow或者任何其他支持事件的对象 (比如 XMLHttpRequest)

addEventListener()的工作原理是将实现EventListener的函数或对象添加到调用它的EventTarget上的指定事件类型的事件侦听器列表中。

语法

target.addEventListener(type, listener, options);target.addEventListener(type, listener, useCapture);target.addEventListener(type, listener, useCapture, wantsUntrusted );  // Gecko/Mozilla only

addEventListener() 除了事件类型 type 和 回调函数 listenner 外,还有一个可选参数 optionsoptions 传入一个可选参数对象,主要包括四个参数,其中preventDefault() 不生效问题就是有 passive 这个参数引起的。

tartget.addEventListenner(type, listener, {    capture: Booolean,    once: Boolean,    passive: Boolean,    signal: AbortSignal})

passive 用于控制是否调用 preventDefault() ,在以前,passive 默认是为 true,即 addEventListener() 中写了 event.preventDefault() 会被正常调用。后来,人们发现 passive 设置为 true 会降低滚屏性能。为什么呢?事件监听器在监听事件时,并不能提前知道回调函数中是否会阻止默认行为,因此若想知道是否会阻止就需要等待函数执行完,这段时间虽然很短,但等待仍会让人感到卡顿。卡顿对比请看下图。而大部分事件监听器是不会阻止默认行为的,所以大部分情况下页面因为等待是否会有 preventDefault() 是完全没必要的,会影响大部分情况下的体验。为解决卡顿问题,某些浏览器就将一些节点事件的 passive 默认为 true,即使函数中使用了 preventDefault() 也会被无视,因为看到 preventDefault() 时浏览器可能已经执行了默认行为,总不能撤回吧(doge) 。

解决方案

前面扯了这么多,但解决很简单,把 passive 设置为 false 传进监听器就行了

document.addEventListener("touchstart", function (ev) {    ev = ev || event;    ev.preventDefault();}, {passive: false});

参考文献

1. MDN Web Docs:EventTarget.addEventListener()

2. MDN Web Docs:使用 passive 改善的滚屏性能

posted @ 2022-02-08 20:41 WindChen 阅读(1) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员