移动端Touch事件preventDefault以后影响click事件触发的不科学解决方案

[2016年1月份,研究了一下这个话题,但没有弄出一个靠谱的案例,现在更新了一个相对靠谱的解决方案]

最近一段时间有做到移动端页面的项目,有接触到有关于touch事件(touchstart,touchmove,touchend)。

在这段时间的开发中,总遇到touchstart与touchend配合的问题。

Touch事件阻止默认事件时解决与a标签的矛盾

在移动端的浏览器中,经测试safari、android自带、chrome、firefox等浏览器都能正常的触发touchend事件。

但问题来了,touchend事件总是无法在微信浏览器触发,验证后发现包括QQ浏览器的X5内核与UC等国产浏览器都存在这个问题。

查了资料知道,要在touchstart中阻止默认事件

event.preventDefault()

好了,成功触发touchend事件了,但问题又来了……A标签等需要点击触发事件的标签失效了。

查资料什么一时之间也不知道查什么关键词,于是乎,放下了这个问题一段时间。

前几日有做到侧边栏滑出菜单,这个问题又来了。本打算通过循环不断为a标签绑定touch事件,但这样确实太麻烦了。

无奈之下,将event通过console.log打印在控制台中仔细查看,最终确定思路:

var startX,startY,startTime;
document.querySelector('#nav').addEventListener('touchstart',function(e){
    e.preventDefault();
    // 记录下触发的坐标和时间
    startTime = (new Date()).getTime();
    startX = e.targetTouches[0].clientX;
    startY = e.targetTouches[0].clientY;
},false);
document.querySelector('#nav').addEventListener('touchend',function(e){
    e.preventDefault();
    var now = (new Date()).getTime();
    // 小于300ms可以识别为点击事件的范围 然后判断触摸点的移动距离
    if (now - startTime < 300) {
       var x = (Math.abs(startX - e.changedTouches[0].clientX) < 30);
       var y = (Math.abs(startY - e.changedTouches[0].clientY) < 30);
       if (x && y) {
           e.changedTouches[0].target.click();
       }
    }
},false);

这个方法的思路主要是,第一,一次点击的时间是300毫秒内的;第二,开始和离开的触摸点滑动的范围很小,只要绝对值在30-50以内的,都可以算为一次点击事件,然后利用click()触发原有点击效果。

这个对select的触发有问题,暂时没有相关的搞法。


2017年8月7日 更新内容,增加时间范围概念和触摸点差值范围感念

阅读: 10443
在同意共创许可协议(CC BY-NC-SA-4.0)的前提下,您可以转载本文。
橙色阳光
https://oss.so/article/65

相关阅读

留言评论

1条留言
柒柒
先赞再说

精品域名

出售精品域名 Yumi.La ¥5000.00