使用Javascript防止移动Safari / iPhone中的触摸事件的鼠标仿真事件(即点击)
在使用交互式DOM元素的单页JavaScript应用程序中,我发现在“ touchstart-touchmove-touchend
”事件序列之后 ,“ mouseover-mousemove-mousedown-mouseup-click
”
我也发现可以通过在touchstart
事件中执行“ event.preventDefault()
”来防止“ mouse*-click
”事件发生,但是只有这样,而不是在touchmove
和touchend
。 这是一个奇怪的devise,因为在touchstart
期间不可能知道用户是否意图拖动或轻扫,或者只是点击/点击该项目。
我最终设置了一个与时间戳绑定的“ignore_next_click”标志,但这显然不是很干净。
有没有人知道这样做的更好方法,还是我们错过了什么?
请注意,虽然“咔嗒”可以被识别为“ touchstart-touchend
”序列(即没有“ touchmove
”),但某些事情(如键盘input焦点)只能在正确的click
事件中发生。
我遇到了类似的问题,使跨平台的HTML5 / JS应用程序。 对我来说唯一真正的答案是防止触摸事件的默认 ,并根据我的逻辑实际pipe理触摸状态并点击,拖动等。 这听起来比实际上更让人望而生畏,但模拟的点击/鼠标事件在大多数移动浏览器上都能正常工作。
点击和额外的鼠标序列都是为了您的方便(和兼容性)。 我的经验法则 – 如果是为了您的方便,但不方便,最好杀死它。
至于input框,他们只需要观看事件。 我已经杀死了点击/鼠标事件,并且仍然能够让移动浏览器正确地响应input。 如果问题仍然存在,则可以修改事件处理程序以仅禁止非input事件:
function touchHandler(event) { var shouldIgnore = event.target != null && ( event.target.tagName.toLowerCase() == "input" || event.target.tagName.toLowerCase() == "textarea" ); if(!shouldIgnore) e.preventDefault(); }
我自己做了一个解决scheme,因为我还没有在其他地方find足够的解决scheme:
var isTouch = ('ontouchstart' in window); function kill(type){ window.document.body.addEventListener(type, function(e){ e.preventDefault(); e.stopPropagation(); return false; }, true); } if( isTouch ){ kill('mousedown'); kill('mouseup'); kill('click'); kill('mousemove'); }
isTouch
的检查让事情在鼠标input设备上正常工作,但杀死Safari / iOS上的模拟事件。 诀窍是在调用addEventListener
使用useCapture = true
,这样我们就可以在页面中获取所有的鼠标事件,而不需要在整个Web应用程序中隐藏代码。 请参阅此处的文档: https : //developer.mozilla.org/en-US/docs/DOM/EventTarget.addEventListener?redirectlocale= zh-CN &redirectslug=DOM%2Felement.addEventListener
编辑:
现在图书馆处理这个问题更好,你可以使用像Fastclick作为替代( https://github.com/ftlabs/fastclick )。
如果您必须支持同时支持鼠标和触摸的设备,另一个解决scheme是使用捕获事件侦听器,该侦听器可以停止发生的所有鼠标事件
- 在触摸事件之后的延迟内
- 与触摸事件处于相同的位置
- 在与触摸事件相同的目标元素上
触摸事件的信息(时间,位置或目标元素)可以logging在另一个捕获事件监听器中。
为移动Web应用程序创build快速button可解决该问题。
另外请注意,当使用IE10时,preventDefault()不会在MSPointerDown事件之后停止ghost / synthetic / emulated鼠标事件,因此真正的跨浏览器解决scheme更困难。