移动端touch事件影响click事件以及在touchmove添加preventDefault导致页面无法滚动的解决方法

简介: 移动端touch事件影响click事件以及在touchmove添加preventDefault导致页面无法滚动的解决方法

这两天自己在写一个手机网页,用到了触屏滑动的特效,就是往右滑动的时候左侧隐藏的菜单从左边划出来。


做完之后在手机原生浏览器中运行正常,但在QQ和微信中打开,发现touchmove只会触发一次,而且touchend也经常不触发。


之后百度了一下这个问题,原因是

主要是由于200ms超时导致内核不一定会一直处理touchmove事件,一旦超时会将后续所有的事件转交给UI处理,导致touchmove不会一直触发。

为了解决开发者需要,建议开发者在touchstart时调用event.preventDefault,这样就可以保证内核会一起触发touchmove事件了。


地址:http://bbs.mb.qq.com/thread-201794-1-1.html

根据上面所说,在touchstart中添加了event.preventDefault()方法,在QQ和微信中果然正常了。


但是!!!页面中的超链接点击没反应了!!!给其他地方加的click事件也不触发了!!!


之后继续百度,得知当在移动端上点击屏幕时,会依次触发touchstart,touchmove,touchend,click事件。


之后测试了一下,发现正确的触发过程应该是:touchstart→touchmove→touchend或者touchstart→touchend→click。


如果在点击屏幕的时候手指滑动的话,是不会触发click事件的。

参考地址:http://www.tuicool.com/articles/3QZ7jeV上面说event.preventDefault()的方法,会阻止事件的默认行为。可以通过调用preventDefault()方法,可以阻止后面事件的触发。


我知道event.preventDefault()会阻止a标签默认的动作(跳转到href指定的页面),但是为什么click也不触发了呢?


之后我大胆推测了一下:

会不会是因为在移动端click事件的触发条件就是必须touchstart和touchend同时触发才能触发click呢?

我在touchstart中调用了event.preventDefault方法,是不是让浏览器误以为没有触发touchstart事件,只触发了touchend事件,所以没有触发click事件呢?


之后我删除了touchstart中的event.preventDefault方法,果然超链接和click事件都触发了,但是前面说的问题又出现了,在QQ和微信中touchmove和touchend又出问题了。

怎么办呢?


后来突然脑袋灵光一闪,既然在touchstart中加了event.preventDefault会导致不触发click事件,那我在touchmove中加可以吧?

抱着试一试的心态,果然好了,click能顺利触发,QQ和微信中也没有问题,我以为这样就好了,但是为什么页面不能滚动了?

原来touchmove中添加event.preventDefault方法之后会阻止浏览器默认的滚动。。。

所以页面无法滚动了,之后又去找找找,找了很久一直没找到怎么解决这个问题,突然想起之后用的一个移动端的图片轮播插件,

为什么他们可以左右滑动,不影响click事件和a标签,也不影响页面的滚动。

然后我打开了这个插件的源码,终于在touchmove中找到了答案

在touchmove中有这样一段代码(下面是我自己抄过来简化过的):


var w = x<0?x*-1:x;     //x轴的滑动值
var h = y<0?y*-1:y;     //y轴的滑动值
if(w>h){                //如果是在x轴中滑动
   event.preventDefault();
}

就是在touchmove中判断x轴和y轴的移动值,判断当前是往哪个方向滑动,如果是在x轴上滑动(左右),就调用event.preventDefault()方法,如果是在y轴上滑动(上下),就不调用event.preventDefault()。

然后测试一下,QQ和微信中特效没有问题,click事件和a标签链接也可以顺利触发,页面滚动也没有问题。

所有问题终于解决了。。

 

总结一下:

在QQ和微信(当然还包括其他浏览器,不过我没测试过)中如果有需要用到touch事件做的特效一定要在touchstart或者touchmove中添加event.preventDefault()方法。

在touchstart中如果有event.preventDefault()方法, 将不会触发click事件和a标签方法。在这里可以使用tap代替click,但是a标签的话就不太方便了。

如果在touchmove中有event.preventDefault()方法,最好加上方向判断,当然如果你页面内容不需要滚动条就不需要加判断了。

目录
相关文章
Threejs实现下雨,下雪,阴天,晴天,火焰
Threejs实现下雨,下雪,阴天,晴天,火焰
2892 0
Threejs实现下雨,下雪,阴天,晴天,火焰
|
前端开发
914.【前端】Taro集成towxml渲染markdown文档
914.【前端】Taro集成towxml渲染markdown文档
1403 2
|
存储 人工智能 搜索推荐
详解MySQL字符集和Collation
MySQL支持了很多Charset与Collation,并且允许用户在连接、Server、库、表、列、字面量多个层次上进行精细化配置,这有时会让用户眼花缭乱。本文对相关概念、语法、系统变量、影响范围都进行了详细介绍,并且列举了有可能让字符串发生字符集转换的情况,以及来自不同字符集的字符串进行比较等操作时遵循的规则。对于最常用的基于Unicode的字符集,本文介绍了Unicode标准与MySQL中各个字符集的关系,尤其详细介绍了当前版本(8.0.34)默认字符集utf8mb4。
2911 82
|
JavaScript 前端开发
Vue3动态面包屑的实现
Vue3动态面包屑的实现
670 0
|
移动开发 JavaScript 前端开发
"Vue开发者必看:一篇文章教你如何实现px自动转换vw或rem,轻松应对H5页面响应式设计挑战!"
【10月更文挑战第23天】在Vue项目中实现px到vw或rem的自动转换,可以使用PostCSS插件。首先安装`postcss-loader`,然后添加`postcss-px-to-viewport`和`postcss-pxtorem`插件,并在`postcss.config.js`中配置。配置完成后,直接在Vue组件中使用px单位编写样式,PostCSS会自动转换为vw或rem。这样可以简化开发流程,提高代码的可维护性和页面的响应式设计能力。
1353 0
|
SQL 关系型数据库 MySQL
云服务器 ECS产品使用问题之出现“1044 - Access denied for user ‘root‘@‘%‘ to database ‘数据库名称‘”这样的错误,该怎么办
云服务器ECS(Elastic Compute Service)是各大云服务商阿里云提供的一种基础云计算服务,它允许用户租用云端计算资源来部署和运行各种应用程序。以下是一个关于如何使用ECS产品的综合指南。
|
JavaScript 前端开发 UED
教你用vue自定义指令做一个组件的遮罩层loading效果
教你用vue自定义指令做一个组件的遮罩层loading效果
1268 0
|
开发工具 git Windows
Mac - git 安装 gitk(详细流程)
Mac - git 安装 gitk(详细流程)
1211 0
移动端click事件、touch事件、tap事件的区别
移动端click事件、touch事件、tap事件的区别
896 0
|
前端开发 C++
一种用markdown写PPT的方法,再也不用费劲排版了
一种用markdown写PPT的方法,再也不用费劲排版了
一种用markdown写PPT的方法,再也不用费劲排版了