- useHabitDrag: onDrop 经 ref 桥接实时闭包 —— bind/bindHandle 空依赖 useCallback 固化了首次渲染(groups=[] 数据未加载)的落位函数, 松手 静默早退, 顺序永远不变 - 把手路径挂非 passive touchstart preventDefault: 规范上禁止浏览器对 整个触摸的默认处理 (含滚动), 与 touch-action:none 双保险 - 把手触区放大 (36px 高), 降低按到行体触发不可靠长按路径的概率
This commit is contained in:
@@ -59,12 +59,15 @@ export default function useRowDrag({ columns, onDrop }) {
|
||||
cleanup()
|
||||
}
|
||||
|
||||
// 指针监听装配 (capture + 非 passive touchmove: 激活后尽力拦截滚动接管)
|
||||
const armListeners = (ev) => {
|
||||
// 指针监听装配 (capture + 非 passive touchmove: 激活后尽力拦截滚动接管;
|
||||
// instant=true 把手路径再挂 touchstart preventDefault, 规范上禁止浏览器对
|
||||
// 整个触摸的默认处理, 彻底杜绝滚动抢占)
|
||||
const armListeners = (ev, instant = false) => {
|
||||
try { ev.currentTarget.setPointerCapture(ev.pointerId) } catch { /* ignore */ }
|
||||
const el = ev.currentTarget
|
||||
const move = (e2) => onMove(e2)
|
||||
const tm = (e2) => { if (st.current.active) e2.preventDefault() }
|
||||
const ts = (e2) => e2.preventDefault()
|
||||
const up = () => { onUp(); detach() }
|
||||
const cancel = () => {
|
||||
if (st.current.active) lastEnd.current = Date.now()
|
||||
@@ -76,11 +79,13 @@ export default function useRowDrag({ columns, onDrop }) {
|
||||
el.removeEventListener('pointerup', up)
|
||||
el.removeEventListener('pointercancel', cancel)
|
||||
el.removeEventListener('touchmove', tm)
|
||||
el.removeEventListener('touchstart', ts)
|
||||
}
|
||||
el.addEventListener('pointermove', move)
|
||||
el.addEventListener('pointerup', up)
|
||||
el.addEventListener('pointercancel', cancel)
|
||||
el.addEventListener('touchmove', tm, { passive: false })
|
||||
if (instant) el.addEventListener('touchstart', ts, { passive: false })
|
||||
}
|
||||
|
||||
/** 绑定到列表行: 行元素需设置 touch-action: pan-y (长按路径, 可滚场景不可靠) */
|
||||
@@ -115,7 +120,7 @@ export default function useRowDrag({ columns, onDrop }) {
|
||||
st.current.active = true
|
||||
if (navigator.vibrate) navigator.vibrate(15)
|
||||
setDrag({ task, fromIdx, toIdx: fromIdx })
|
||||
armListeners(ev)
|
||||
armListeners(ev, true)
|
||||
},
|
||||
onContextMenu: (ev) => ev.preventDefault(),
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
||||
Reference in New Issue
Block a user