Skip to content

fix: 面板拖拽排序改用指针事件,手机端可用 - #92

Merged
stqfdyr merged 4 commits into
monitor-probe:mainfrom
vansour:fix/admin-drag-pointer-events
Oct 6, 2026
Merged

stqfdyr merged 4 commits into
monitor-probe:mainfrom
vansour:fix/admin-drag-pointer-events

Conversation

@vansour

@vansour vansour commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

拖拽排序原来只在电脑端能用:它靠 HTML5 拖放,触屏上按住手柄不会开始拖动;Android 上长按能合成一次拖动,但 dragend 的 dropEffect 恒为 "none",每次放手都被当成取消,顺序原样弹回。

  • useDragOrder 的输入改为 Pointer Events,鼠标、触摸、触控笔走同一条路径;手指按下手柄即拿起
  • 指针捕获由 tbody 持有:被拖的行换位时会在文档里被挪动,挂在它上面的捕获会丢,拖出窗口松手就收不到
  • 触屏拖动时页面不滚动(touch-action: none),朝视口上下边缘拖时自动滚动,越靠边越快;在靠边的行上按住不动不会滚。页面滚动(自动滚动或滚轮)时按指针最后的位置重算落点
  • Esc 取消、拖出表格松手还原改为自行实现;松手没被收到(如拖动中弹出右键菜单)时,下一次不按键的移动即取消
  • 拖动中全页保持 grabbing 光标(拖动起止各给根元素打一次标记,换位时不触发整页样式重算);粗指针下手柄的触摸目标放大
  • 换位几何、变高行防抖、slide 动画、保存串行与键盘 ↑↓ 不变

验证:lint、test、build 通过。桌面 Chromium:拖动换位并保存、拖出表格与 Esc 还原、拖动中滚轮滚动后落点跟随、底边自动滚动、键盘排序,拖动全程捕获不丢、不产生文字选区;漏掉松手后不再跟随悬停换位;底边按住不动不滚动;200 台节点拖动 40 步的样式重算约 16 ms。Android 17 + Chrome 149 模拟器真实触摸:按下即拖、长按 1.2 秒后再拖、拖到底边自动滚动,均正确保存,长按不弹菜单、不选中文字。iOS 未实测。

拖拽排序原来依赖 HTML5 拖拽事件,它只能由鼠标发起:触屏上不产生 dragstart,
手柄按住没有任何反应;Android 上即便合成拖拽,dragend 的 dataTransfer.dropEffect
也恒为 "none",每次放手都被判成取消,顺序原样弹回。

- 手柄改为 pointerdown 起拖,pointermove/pointerup/pointercancel 挂在文档上,
  鼠标、触摸、触控笔走同一条路径;setPointerCapture 让指针移出窗口也能收到抬手;
  多指只认第一根,鼠标只认左键
- 触屏手势被 touch-action: none 捕获后页面不再滚动,补上边缘自动滚动:rAF 循环
  按接近度加速,指针停住时按最后坐标重算落点
- Esc 取消与拖出表格还原改为自行实现,原来由浏览器取消原生拖拽附带完成
- 手指按下即拿起,不等长按;手柄补 select-none、-webkit-touch-callout: none 与
  长按菜单抑制,粗指针下放大触摸目标
- 键盘排序保留原有 ↑↓;新增 aria-live 播报(已移动到第 N 位,共 M 个 / 已取消排序)
- 拖拽期间 body[data-dragging]:全页 grabbing 光标并禁止文本选择
- 几何与动画未动:按布局位置换位、变高行防抖阈值、slide 动画、保存串行保持原样
Copilot AI balanced review requested due to automatic review settings October 4, 2026 14:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…r-events

# Conflicts:
#	web-admin/src/components/Admin.tsx
- 指针捕获改由 tbody 持有:向下拖时被拖的行会在 DOM 里被挪动,挂在手柄上的捕获随之丢失,拖出窗口松手收不到
- 页面滚动(自动滚动、滚轮)由 scroll 事件按最后坐标重算落点,自动滚动循环只管滚动,不再每次渲染重启
- 去掉 aria-live 播报、长按菜单抑制、-webkit-touch-callout、select-none、pointerdown 的 preventDefault 与手动聚焦:实测桌面与 Android 都不需要
- 拖动中的光标用 :has() 跟随行上的 data-dragging,不再给 body 打标记
- 没按键的 pointermove 说明松手没被看到(如拖动中弹出右键菜单),这时取消拖动,不再让行跟着悬停换位、下次点击时误存
- 自动滚动只朝指针离开按下位置的方向滚:在靠边的行上按住不动,页面不再滚动、行不再自己换位;首帧不再出现负的时间差
- grabbing 光标改由拖动开始和结束时给根元素打标记,不用 :has():200 台节点拖动 40 步,样式重算从约 370 ms 降到约 16 ms
- 手柄加回 select-none;注释的反事实改用 would
@stqfdyr
stqfdyr merged commit b0287c3 into monitor-probe:main Oct 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants