
移动端Touch事件preventDefault以后影响click事件触发的不科学解决方案
关于Touch事件影响到click事件,建议把preventDefault放入到touchmove事件中,模拟触发的click始终不是一个好方案。
[2016年1月份,研究了一下这个话题,但没有弄出一个靠谱的案例,现在更新了一个相对靠谱的解决方案]
最近一段时间有做到移动端页面的项目,有接触到有关于touch事件(touchstart,touchmove,touchend)。
在这段时间的开发中,总遇到touchstart与touchend配合的问题。
在移动端的浏览器中,经测试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日 更新内容,增加时间范围概念和触摸点差值范围感念