使用Javascript防止移动Safari / iPhone中的触摸事件的鼠标仿真事件(即点击)

在使用交互式DOM元素的单页JavaScript应用程序中,我发现在“ touchstart-touchmove-touchend ”事件序列之后 ,“ mouseover-mousemove-mousedown-mouseup-click

我也发现可以通过在touchstart事件中执行“ event.preventDefault() ”来防止“ mouse*-click ”事件发生,但是只有这样,而不是在touchmovetouchend 。 这是一个奇怪的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更困难。