为什么你的处理程序在移动设备上触发两次,以及拖动后的 Click
关于画布上的指针输入,有两件事经常让人感到意外。一件是真正需要处理的问题,另一件已经由系统处理好了,了解这一点可以避免使用不必要的变通方案
一次点击可能触发三个事件
Konva 会监听全部三种 DOM 输入系列——鼠标、触摸和指针——这样处理程序无需提前选择,就能在任何设备上工作。它不会将这些事件合并
在触摸屏上,浏览器会发送一对 touchstart/touchend,一对 pointerdown/pointerup,然后为了兼容触摸出现之前编写的页面,合成 mousedown/mouseup。Konva 会将其中每一对都转换为自己的事件。一次点击会产生:
| Konva 事件 | 来源 |
|---|---|
tap | 触摸事件对 |
pointerclick | 指针事件对 |
click | 合成的鼠标事件对 |
因此,这段代码在手机上会运行你的处理程序两次,在桌面设备上运行一次:
// Fires for `click` and again for `tap` on a touch device.
shape.on('click tap', handleSelect);
绑定一个系列
最简单的修复方法是停止配对事件,改用指针系列,它已经覆盖鼠标、触摸和触控笔:
shape.on('pointerclick', handleSelect); // once, on every device
pointerdown、pointermove 和 pointerup 的工作方式相同。指针事件默认启用(Konva.pointerEventsEnabled),更多信息请参阅 Pointer Events
如果你需要支持不提供指针事件的浏览器,或者正在维护已经配对 click tap 的代码,也可以改为保护处理程序:
let lastHandled = 0;
function handleSelect(e) {
// A synthesised mouse event follows its touch within about 300ms.
const now = Date.now();
if (now - lastHandled < 400) return;
lastHandled = now;
// ...
}
优先绑定一个系列。计时器只是一个变通方案,并且会吞掉快速用户发起的真正第二次点击