使用hammer.js拖动元素会在移动版

时间:2018-02-20 01:15:09

标签: 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;">
  <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)    
})

我创建了一个Fiddle来演示。在移动设备上,如果我将手指放在圆圈的中心并且移动得非常慢,我会看到圆形轨道很短的一段时间,但突然中心跳到0,0,而在桌面上它会跟随所有指针一天。

我创建了一个Updated Fiddle,会在panstartpancancelpanend事件发生时显示。我所看到的是,当圆圈跳到原点时,我得到pancancel事件。为什么我的平底锅被取消了,即使我还没有从屏幕上抬起手指?

更奇怪的是this version。我所做的只是颠倒了跨度的顺序(显示了panstartpancancelpanend发生了多少次的计数器。如果跨度 SVG之后,那么突然我可以平移圆圈,但仅水平。但是如果跨度之前或者那里没有,那么在少量手指移动之后平移就会突然取消。好的,原来它是元素那个滚动,而不是圆圈。然而,版本41在桌面上也表现得很奇怪...当我第一次尝试它时,我根本无法响应鼠标事件,但它开始工作,然后再次停止,所有这一切都只需更改到不同的版本和返回。

更新:为了了解调用pancancel回调的原因,我检查了hammer.js的副本。 PanRecognizer directionTest函数(第1778行)返回false,导致生成取消。发生的事情总是某种形式的&#34;什么都没发生&#34;,导致hasMoved为假,或者距离为0(我尝试将阈值设置为-1,但这只是在问题出现的地方移动了) ,或方向为DIRECTION_NONE。

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

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

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

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

2 个答案:

答案 0 :(得分:0)

我记得我只需要添加jquery.ui.touch-punch.js,它在移动设备上运行良好

库:

http://touchpunch.furf.com/

答案 1 :(得分:0)

迈克尔,我遇到了和你一样的问题。我已经通过示例和视频在GitHub上提交了bug report。有趣的是看到你发现它与浏览器触发的“pointercancel”有关,但到目前为止它还没有帮我弄清楚如何修补这个问题。你有没有在这个问题上取得任何进展?

作为参考,这个StackOverflow thread讨论了同样的问题。不幸的是,到目前为止,没有一个修复程序可以用于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
    );