我正在处理接口,以允许用户使用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,而在台式机上,它沿着全部指针遵循指针一天。
我创建了一个更新的小提琴,该小提琴会在发生panstart
,pancancel
和panend
事件时显示。我看到的是,当圆圈跳到原点时,我将获得pancancel
事件。为什么即使我还没有从屏幕上抬起手指,为什么我的锅也会被取消?
甚至是陌生人这个版本。我所做的只是扭转跨度的顺序(其中显示了发生了多少次panstart
,pancancel
和panend
的计数器(。如果跨度在之后,那么突然间,我可以将圆圈放在圆圈中,但是仅水平。但是,如果跨越之前或不存在的跨度,则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/