HTML5 Drag and Drop API (draggable, dragstart, drop, v.v.) không hoạt động trên thiết bị cảm ứng (mobile/tablet) mặc định. Cần thư viện polyfill hoặc xử lý sự kiện touch.
Giải pháp khuyến nghị
- SortableJS – Nhẹ, không phụ thuộc, hỗ trợ touch, drag handle, nested list, animation. Phổ biến nhất.
- @dnd-kit/core – Headless, accessible, TypeScript first, React/Vue/Svelte ready.
- react-beautiful-dnd – Chỉ React, đẹp, accessible (đã archived, dùng @hello-pangea/dnd).
- jQuery UI Touch Punch – Polyfill cũ, biến touch events thành mouse events cho jQuery UI. Không khuyến cho project mới.
Các sự kiện Drag & Drop (Desktop)
| Sự kiện | Phát ra từ | Mô tả |
|---|---|---|
dragstart | Kéo | Bắt đầu kéo – set dataTransfer |
drag | Kéo | Đang kéo (fire liên tục) |
dragenter | Drop zone | Vào vùng drop |
dragover | Drop zone | Đang ở trên vùng drop (preventDefault() để cho drop) |
dragleave | Drop zone | Rời vùng drop |
drop | Drop zone | Thả – lấy dataTransfer |
dragend | Kéo | Kết thúc kéo (dù thành công hay không) |
Làm thủ công cho Touch (nếu không dùng thư viện)
element.addEventListener('touchstart', handleStart, {passive: false});
element.addEventListener('touchmove', handleMove, {passive: false});
element.addEventListener('touchend', handleEnd);
function handleStart(e) {
e.preventDefault(); // Ngăn scroll
const touch = e.touches[0];
// Lưu vị trí bắt đầu, clone element, v.v.
}
Khuyến nghị mạnh mẽ: Dùng SortableJS hoặc @dnd-kit thay vì tự viết – xử lý edge case phức tạp (scroll container, auto-scroll, accessibility, multi-touch).