Pointer Capture 讓滑鼠離開元件仍能收事件
拖曳/繪製類互動的標準做法:pointerdown 時呼叫 setPointerCapture(pointerId),這之後不管游標移到哪、即使離開元件甚至離開瀏覽器視窗,所有 pointermove、pointerup 都會被導回該元件。
做法
const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
containerRef.current?.setPointerCapture(e.pointerId)
// 開始拖曳/繪製...
}
const onPointerUp = (e: React.PointerEvent<HTMLDivElement>) => {
if (containerRef.current?.hasPointerCapture(e.pointerId)) {
containerRef.current.releasePointerCapture(e.pointerId)
}
// 結束...
}注意要綁 onPointerCancel 也指向同一個 handler,避免系統中斷拖曳時狀態洗不掉。
沒有 Pointer Capture 會發生什麼
使用者按下開始拖、滑出元件再放開 → pointerup 落在外面、你的元件收不到 → 拖曳狀態永遠不會清乾淨 → 之後游標飄回來自動繼續拖(鬼影 bug)。
過去的 workaround 是「mousedown 時 window.addEventListener('mousemove'/'mouseup'),結束時記得 remove」,繁瑣又容易漏 cleanup。Pointer Capture 從根本解決,DOM API 內建。
適用場景
- 畫布拖移、繪製、選取框
- Slider、Resize handle、Splitter
- 自製 drag-and-drop
- 任何「按下開始、放開結束」的互動
Pointer 比 Mouse 多了什麼
- 同時處理滑鼠 + 觸控 + 筆,一套 API 搞定
pointerId可以區分多指觸控- 內建
setPointerCapture,不必再 hackwindow事件
幾乎沒有理由再用 mousedown/mousemove/mouseup 三件套。