【发布时间】:2018-07-30 07:11:36
【问题描述】:
我正在开发一个界面,以允许用户使用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,它在panstart、pancancel 和panend 事件发生时显示。我看到的是,当圆圈跳到原点时,我得到了一个 pancancel 事件。为什么我的手指还没有离开屏幕,但我的平移却被取消了?
更陌生的是this version。我所做的只是颠倒跨度的顺序(显示计数器出现了多少次好吧,原来是滚动的元素,而不是圆圈.但是,版本 41 在桌面上的行为也很奇怪......当我第一次尝试它时,我根本无法让它响应鼠标事件,但随后它开始工作,然后又停止了,所有这一切只需更改为不同的版本和返回。panstart、pancancel 和panend)。如果跨度在 SVG 之后,那么我突然可以平移圆圈,但只能水平地平移。但如果跨度在之前或不存在,那么在手指移动一小段时间后,平移就会突然取消。
更新:为了弄清为什么调用pancancel 回调,我检测了hammer.js 的副本。 PanRecognizer directionTest 函数(第 1778 行)返回 false,导致生成取消。所发生的总是某种形式的“什么都没发生”,导致 hasMoved 为假,或距离为 0(我尝试将阈值设置为 -1,但这只是移动到问题出现的地方),或者方向为 DIRECTION_NONE。
这仍然没有多大意义 - 即使我以足够快的速度平移,我也不应该在两个事件之间获得零移动,即使我缓慢平移我也不会'没想到这会是个问题。
更新 2: 我添加了以下工具:
Hn1.on("hammer.input",function(ev) {
console.log("debug",ev)
})
当我这样做时,我看到一个源事件pointercancel,这表明浏览器正在取消实际上正在使用中间的指针运动。在查看此事件的documentation 时,提到的取消指针事件的四个原因均不适用于这种情况。这是怎么回事?!
【问题讨论】:
-
FWIW 我找到了workaround,尽管我仍然希望更好地描述为什么会发生这种情况,以及可能不是那么笨拙的解决方案。
标签: javascript hammer.js