用Hammer.js拖动元素在移动设备上失败



我正在处理接口,以允许用户使用hammer.js在屏幕上拖动对象。在桌面浏览器中,它可以工作,但是在移动设备上拖动它时,它可以短暂起作用,然后突然起作用,好像事件的客户端坐标突然达到0,0。

我有一个简单的SVG圆圈,我正在尝试拖动:

<svg version="1.1" viewBox="0 0 640 480" id="svg" style="width: 640px; height: 480px; top:0px; left: 0px; position: absolute;">
  <circle class="selhan" cx="320" cy="240" r="200" id="circ" 
   style="fill: none; stroke: rgb(0, 0, 0); pointer-events: all; 
   touch-action: none; user-select: none; -webkit-user-drag: none; 
   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">
  </circle>
</svg>

我正在设置一个简单的pan处理程序:

var circ = document.getElementById("circ")
var Hn1=new Hammer(circ, {/*domEvents:true*/})
Hn1.add( new Hammer.Pan({ direction: Hammer.DIRECTION_ALL, threshold: 0, pointers:1 }) )
var X0,Y0
Hn1.on("panstart", function(e) {
    var ob = e.target
    var cx = ob.getAttribute("cx")
    var cy = ob.getAttribute("cy")
    X0=e.center.x-cx
    Y0=e.center.y-cy
})
Hn1.on("pan", function(e) {
        var ob = e.target
        var X = e.center.x-X0
        var Y = e.center.y-Y0
        ob.setAttribute("cx",X)
        ob.setAttribute("cy",Y)    
})

我创建了一个小提琴来演示。在移动设备上,如果我将手指放在圆圈的中心并非常缓慢地移动,我会在短时间内看到圆形轨道,但是突然间,中心跳至0,0,而在台式机上,它沿着全部指针遵循指针一天。

我创建了一个更新的小提琴,该小提琴会在发生panstartpancancelpanend事件时显示。我看到的是,当圆圈跳到原点时,我将获得pancancel事件。为什么即使我还没有从屏幕上抬起手指,为什么我的锅也会被取消?

甚至是陌生人这个版本。我所做的只是扭转跨度的顺序(其中显示了发生了多少次panstartpancancelpanend的计数器(。如果跨度之后,那么突然间,我可以将圆圈放在圆圈中,但是仅水平。但是,如果跨越之前或不存在的跨度,则panning在短量的手指运动后突然取消。。但是,版本41在台式机上也表现出奇怪的行为...当我第一次尝试时,我无法让它完全响应鼠标事件,但后来它开始工作,然后它再次停止,仅通过简单地更改为不同版本和背面。

更新:为了探讨为什么要调用pancancel回调的底部,我启动了我的Hammer.js副本。PanRecognizer directionTest函数(第1778行(返回false,导致取消生成。发生的事情总是是某种形式的"什么都没发生",导致 hasMoved是错误的,或者距离为0(我尝试将阈值设置为-1,但这只是在出现问题的地方移动(或方向_none。

这仍然没有很多意义 - 即使我以足够快的速度平移,我也不会在两个事件之间获得零移动,即使我慢慢地平移,我也不会期望这是一个问题。

更新2:我添加了以下仪器:

    Hn1.on("hammer.input",function(ev) {
        console.log("debug",ev)
    })

当我这样做时,我会看到一个源事件pointercancel,该事件表明浏览器实际上使用了IS中间的指针运动。在审查此事件的文档时,在这种情况下,没有提到的指示事件的四个原因都不适用。这里发生了什么?!

迈克尔,我和你遇到了同一问题。我已经在GitHub上提交了一个错误报告,并进行了示例和视频。有趣的是看到您发现它与浏览器触发的" PointerCancel"有关,但是到目前为止,它还没有帮助我弄清楚如何修补此问题。您在此事上取得了任何进展吗?

供参考,此stackoverflow线程讨论了同一问题。不幸的是,到目前为止,没有一个修复程序为我为Hammerjs工作。

编辑:事实证明,防止窗口上的默认" touchMove"事件处理将解决页面上任何SVG元素的问题。这是个好消息,但它也可以禁用页面上的所有滚动行为。相反,我所做的就是在SVG对象上捕获"触摸机"事件,因此其中的任何后代都可以正确地锅。我还不确定它是否有任何不良副作用,但是到目前为止,这意味着我在SVG中的平移终于在Android浏览器上工作!

为了完整的缘故,这是必要的代码:

const options = { passive: false }; // needed because Chrome has this set to "true" by default for "touchmove" events
    mySVG.addEventListener(
      "touchmove",
      e => e.preventDefault(),
      options
    );

我只记得我只需要添加jquery.ui.touch-punch.js,并且在移动设备上正常工作

库:

http://touchpunch.furf.com/

相关内容

最新更新