Javascript 在mobile上使用hammer.js拖动元素失败

Javascript 在mobile上使用hammer.js拖动元素失败,javascript,hammer.js,Javascript,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;"> &l

我正在开发一个界面,允许用户使用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>
我创建了一个示例来演示。在移动设备上,如果我把手指放在圆圈的中心,移动得非常慢,我会看到圆圈的轨迹很短一段时间,但是突然中心跳到了0,0,而在桌面上,它整天都跟着指针

我创建了一个在
panstart
pancancel
panend
事件发生时显示的。我看到的是,当圆跳到原点时,我得到了一个
pancancel
事件。为什么我的平移被取消了,即使我的手指还没有从屏幕上抬起

甚至陌生人也是。我所做的只是颠倒跨距的顺序(显示发生了多少次
panstart
pancancel
panend
的计数器)。如果跨距位于SVG之后,那么我可以突然平移圆,但只能水平平移。但是,如果跨距出现在之前或不存在,则平移会在手指短时间移动后突然取消。好的,结果是滚动的是元素,而不是圆。然而,41版在桌面上的表现也很奇怪。。。当我第一次尝试它时,我根本无法让它响应鼠标事件,但后来它开始工作,然后又停止了,所有这些都是通过简单地切换到不同的版本并返回

更新:为了弄清调用
pancancel
回调的原因,我插入了的副本。PanRecognizer
directionTest
功能(第1778行)返回false,导致生成取消。发生的总是某种形式的“什么都没发生”,导致
hasmove
为false,或者距离为0(我尝试将阈值设置为-1,但这只是在出现问题的地方移动),或者方向为direction\u NONE

这仍然没有太多的意义-我看到这种情况发生,即使当我以足够快的速度平移时,我永远不会在两个事件之间获得零移动,即使我平移缓慢,我也不会认为这是一个问题

更新2: 我添加了以下工具:

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

当我这样做时,我看到一个源事件,表明浏览器正在取消实际上正在使用的指针中间的指针运动。在查看此事件的原因时,指针事件被取消的四个原因均不适用于此情况。这是怎么回事

我刚想起我只需要添加jquery.ui.touch-punch.js,它在手机上运行良好

图书馆:


迈克尔,我遇到了和你一样的问题。我已经在GitHub上提交了一个示例和视频。有趣的是,你发现它与浏览器触发的“pointercancel”有关,但到目前为止,它还没有帮助我找到解决这个问题的方法。你在这件事上有什么进展吗

作为参考,这篇文章讨论了同样的问题。不幸的是,到目前为止,对于HammerJS,没有一个修复对我有效

编辑: 事实证明,阻止窗口上的默认“touchmove”事件处理将解决页面上任何SVG元素的此问题。这是个好消息,但它也禁用了页面上的所有滚动行为。相反,我所做的是捕获SVG对象上的“touchmove”事件,以便其中的任何子体都能正确平移。我还不确定它是否有任何不良副作用,但到目前为止,这意味着我在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
    );

我不太明白。。。hammer.js没有像jQuery这样的任何其他库要求。你是在建议我用jQuery和touch punch替换hammer吗?FWIW我找到了一个解决方案,尽管我仍在寻找一个更好的描述为什么会发生这种情况的方法,并且一个解决方案可能不是那么困难。目前我已经取得的进展是不使用hammer,我们实际上需要了解的是,最终需要的不是完全的手势支持,hammer providesCool,很高兴你找到了解决方法。
const options = { passive: false }; // needed because Chrome has this set to "true" by default for "touchmove" events
    mySVG.addEventListener(
      "touchmove",
      e => e.preventDefault(),
      options
    );