问题

移动端 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 改善的滚屏性能

Web:移动端阻止默认行为的小坑的更多相关文章

  1. python 函数默认值的小坑啊

    import datetime import time def test(day=datetime.datetime.now()): print day while True: test() time ...

  2. javascript小实例,阻止浏览器默认行为,真的能阻止吗?支持IE和标准浏览器的阻止默认行为的方法

    看到这标题,是不是有点逆天的感觉,总感觉好狂拽炫酷,耳边隐隐约约传来一个声音:你这么叼,你咋不上天呢! ~~ 额,好吧! 话入正题,我为什么会提出这么一个问题呢? 阻止浏览器默认行为,真的能阻止吗?那 ...

  3. 跨界!Omi 发布多端统一框架 Omip 打通小程序与 Web 腾讯开源 2月28日

    https://mp.weixin.qq.com/s/z5qm-2bHk_BCJAwaodrMIg 跨界!Omi 发布多端统一框架 Omip 打通小程序与 Web 腾讯开源 2月28日

  4. web移动端常见问题解决方案 (转)

    总结:本文总结了web移动端的常见问题并附上解决方案,包括:Meta标签.获取滚动条的值.禁止选择文本.屏蔽阴影.css之border-box.css3多文本换行.Retina屏幕高清图片.html5 ...

  5. [总结]CSS/CSS3常用样式与web移动端资源

    CSS/CSS3常用样式与知识点 IE条件注释 条件注释简介 IE中的条件注释(Conditional comments)对IE的版本和IE非IE有优秀的区分能力,是WEB设计中常用的hack方法.条 ...

  6. 【转载】Web移动端Fixed布局的解决方案

    特别声明:本文转载于EFE的<Web移动端Fixed布局的解决方案>.如需转载,烦请注明原文出处:http://efe.baidu.com/blog/mobile-fixed-layout ...

  7. web移动端资源整(1)

    meta基础知识 H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=device-wid ...

  8. 从web移动端布局到react native布局

    在web移动端通常会有这样的需求,实现上中下三栏布局(上下导航栏位置固定,中间部分内容超出可滚动),如下图所示: 实现方法如下: HTML结构: <div class='container'&g ...

  9. react 移动端 兼容性问题和一些小细节

    react 移动端 兼容性问题和一些小细节 使用 ES6 的浏览器兼容性问题 react 对低版本的安卓webview 兼容性 iOS下 fixed与软键盘的问题 onClick 阻止冒泡 meta对 ...

随机推荐

  1. 家用路由器也能充当Web服务器?路由器插件开发心得

    起因 最近刚刚结束考研,开始有时间写文章了.在复习的时候中,经常忍不住折腾各种东西,于是有一天看中了我手上的华为路由器.什么?华为路由器,你可能有这样的疑问,华为路由器不是自研的芯片吗,就像我手上这台 ...

  2. RabbitMQ学习笔记四:RabbitMQ命令(附疑难问题解决)

    本来今天是想做RabbitMQ之优先级队列的,但是,在RabbitMQ Server创建queue时,增加优先级的最大值,头脑发热写了9999999,导致电脑内存直接飙到100%,只能重启电脑,并卸载 ...

  3. SuperPixel

    目录 SLIC Superpixel algorithm 距离函数的选择 代码 Gonzalez R. C. and Woods R. E. Digital Image Processing (For ...

  4. Electron 使用 Tray设置图标的路径问题

    问题报错信息如图 上面的代码在dev模式下不报错,但是在build后,安装后,运行会提示错误,错误信息的大意是参数错误,原因应该是安装后的图片文件路径有问题,这块没有详细研究解决上面的问题的方法,是使 ...

  5. 跨域The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.解决方案

    使用Ajax跨域请求资源,Nginx作为代理,出现:The 'Access-Control-Allow-Origin' header contains multiple values '*, *', ...

  6. Java Swing 如何设置图片大小

    如下两行代码搞定: Image image = new ImageIcon("Img/ackground.jpg").getImage();// 这是背景图片 .png .jpg ...

  7. 官网下载mysql的方法

    mysql官网    http://www.mysql.com/ 方法一:    (1)登陆官网 (2)把页面拉到最底部,点击Downloads(GA) 下边的MySQL Community Serv ...

  8. js tab栏切换

    <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...

  9. 【Python+Django+Pytest】数据库异常pymysql.err.InterfaceError: (0, '') 解决方案

    问题背景: 接口自动化测试平台,在执行测试案例之外,还需要做以下五件事情(或步骤): 1.查询用户在数据准备中预置的测试套件层数据初始化相关sql  (setUp_class方法中) 2.查询用户在数 ...

  10. 初识python 之 兔子生崽(小练习)

    题目:有一对兔子,从出生后第三个月起每个月都生一对小兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子不死,每个月的兔子总数为多少?思路分析: 月份 兔子数 规律1 2 2**12 2 2**13 ...