เหตุการณ์ ondrag จะถูกกระตุ้น ซ้ำๆ ตลอดการลาก (Drag) องค์ประกอบ ใช้สำหรับอัปเดต UI แบบเรียลไทม์ขณะลาก ต่างจาก ondragstart (เริ่มลาก) และ ondragend (จบการลาก)
ตัวอย่างการใช้งาน (Drag & Drop ครบวงจร)
<!DOCTYPE HTML>
<html>
<head>
<style>
.drag-zone {
float: left; width: 150px; height: 150px;
border: 2px dashed #876587; margin: 15px; padding: 10px;
background: #fafafa; transition: background 0.2s;
}
.drag-zone.drag-over { background: #e8f5e9; border-color: #4CAF50; }
.draggable { background: #4CAF50; color: white; padding: 15px; text-align: center; cursor: grab; }
#status { clear: both; padding: 15px; background: #fff3e0; font-family: monospace; }
</style>
</head>
<body>
<div class="drag-zone" id="zone1" ondrop="drop(event)" ondragover="dragOver(event)" ondragleave="dragLeave(event)">
<p id="dragItem" draggable="true"
ondragstart="dragStart(event)"
ondrag="dragging(event)"
class="draggable">ลากฉันได้</p>
</div>
<div class="drag-zone" id="zone2" ondrop="drop(event)" ondragover="dragOver(event)" ondragleave="dragLeave(event)">
<p>พื้นที่วางเป้าหมาย</p>
</div>
<div id="status">พร้อมลาก...</div>
<script>
let dragCount = 0;
function dragStart(e) {
e.dataTransfer.setData("text/plain", e.target.id);
e.dataTransfer.effectAllowed = "move";
e.target.style.opacity = "0.5";
dragCount = 0;
}
function dragging(e) {
dragCount++;
// Throttle log (ทุก 50 ครั้ง ~ ทุก ~1 วินาที)
if (dragCount % 50 === 0) {
document.getElementById('status').textContent = `กำลังลาก... (${dragCount} events)`;
}
}
function dragOver(e) {
e.preventDefault(); // สำคัญ!
e.dataTransfer.dropEffect = "move";
e.currentTarget.classList.add('drag-over');
}
function dragLeave(e) {
e.currentTarget.classList.remove('drag-over');
}
function drop(e) {
e.preventDefault();
e.currentTarget.classList.remove('drag-over');
const id = e.dataTransfer.getData("text/plain");
const el = document.getElementById(id);
e.currentTarget.appendChild(el);
el.style.opacity = "1";
document.getElementById('status').textContent = `วางสำเร็จ! (Drag events: ${dragCount})`;
}
</script>
</body>
</html>
เหตุการณ์ Drag Source (ลำดับ)
ondragstart- เริ่มลาก (ตั้งค่า DataTransfer)ondrag- กำลังลาก (ยิงซ้ำๆ ทุก Frame) ⚡ondragend- จบการลาก (ทำความสะอาด, Reset UI)
⚠️ ประสิทธิภาพ ondrag
- ยิง ทุก Animation Frame (~60fps) ขณะลาก
- ❌ ไม่ควรทำงานหนัก (DOM Manipulation, Layout, Network) ใน Handler
- ✅ ใช้
requestAnimationFrameหรือ Throttle (100-200ms) - ✅ ใช้สำหรับ: Update Visual Feedback (Coordinates, Preview), Simple Calculations
ตัวอย่าง Throttle สำหรับ ondrag
function throttle(fn, delay) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= delay) {
lastCall = now;
fn.apply(this, args);
}
};
}
const throttledDrag = throttle((e) => {
// อัปเดต UI Position Preview
updateDragPreview(e.clientX, e.clientY);
}, 50); // 20fps
element.ondrag = throttledDrag;