Drag and Drop Events in JavaScript
Implement drag and drop functionality
AdvancedEvents ProgramsExample 10 of 10
drag-and-drop-events.js
1// Method 1: HTML5 Drag and Drop API2const draggable = document.getElementById('draggable');3const dropzone = document.getElementById('dropzone');45// Make element draggable6draggable.draggable = true;78// Drag events on source9draggable.addEventListener('dragstart', function(e) {10 console.log('Drag started');11 e.dataTransfer.setData('text/plain', draggable.id);12 e.dataTransfer.effectAllowed = 'move';13 draggable.style.opacity = '0.5';14});1516draggable.addEventListener('dragend', function(e) {17 console.log('Drag ended');18 draggable.style.opacity = '1';19});2021// Drop events on target22dropzone.addEventListener('dragover', function(e) {23 e.preventDefault(); // Allow drop24 e.dataTransfer.dropEffect = 'move';25 dropzone.style.backgroundColor = 'lightblue';26});2728dropzone.addEventListener('dragleave', function(e) {29 dropzone.style.backgroundColor = '';30});3132dropzone.addEventListener('drop', function(e) {33 e.preventDefault();34 console.log('Dropped');35 const data = e.dataTransfer.getData('text/plain');36 const element = document.getElementById(data);37 dropzone.appendChild(element);38 dropzone.style.backgroundColor = '';39});4041// Method 2: Custom drag implementation42let isDragging = false;43let currentX, currentY, initialX, initialY;4445const customDraggable = document.getElementById('customDraggable');4647customDraggable.addEventListener('mousedown', function(e) {48 isDragging = true;49 initialX = e.clientX - customDraggable.offsetLeft;50 initialY = e.clientY - customDraggable.offsetTop;51 customDraggable.style.cursor = 'grabbing';52});5354document.addEventListener('mousemove', function(e) {55 if (isDragging) {56 e.preventDefault();57 currentX = e.clientX - initialX;58 currentY = e.clientY - initialY;5960 customDraggable.style.left = currentX + 'px';61 customDraggable.style.top = currentY + 'px';62 }63});6465document.addEventListener('mouseup', function() {66 if (isDragging) {67 isDragging = false;68 customDraggable.style.cursor = 'grab';69 }70});7172// Method 3: Drag with touch support73customDraggable.addEventListener('touchstart', function(e) {74 isDragging = true;75 const touch = e.touches[0];76 initialX = touch.clientX - customDraggable.offsetLeft;77 initialY = touch.clientY - customDraggable.offsetTop;78});7980document.addEventListener('touchmove', function(e) {81 if (isDragging) {82 e.preventDefault();83 const touch = e.touches[0];84 currentX = touch.clientX - initialX;85 currentY = touch.clientY - initialY;8687 customDraggable.style.left = currentX + 'px';88 customDraggable.style.top = currentY + 'px';89 }90});9192document.addEventListener('touchend', function() {93 isDragging = false;94});9596// Method 4: Drag with constraints97function dragWithConstraints(element, minX, minY, maxX, maxY) {98 let isDragging = false;99 let startX, startY, offsetX, offsetY;100101 element.addEventListener('mousedown', function(e) {102 isDragging = true;103 startX = e.clientX;104 startY = e.clientY;105 offsetX = element.offsetLeft;106 offsetY = element.offsetTop;107 });108109 document.addEventListener('mousemove', function(e) {110 if (isDragging) {111 let newX = offsetX + (e.clientX - startX);112 let newY = offsetY + (e.clientY - startY);113114 // Apply constraints115 newX = Math.max(minX, Math.min(maxX, newX));116 newY = Math.max(minY, Math.min(maxY, newY));117118 element.style.left = newX + 'px';119 element.style.top = newY + 'px';120 }121 });122123 document.addEventListener('mouseup', function() {124 isDragging = false;125 });126}127128// Method 5: Sortable list129const sortableList = document.getElementById('sortableList');130131sortableList.addEventListener('dragstart', function(e) {132 if (e.target.tagName === 'LI') {133 e.target.style.opacity = '0.5';134 e.dataTransfer.effectAllowed = 'move';135 e.dataTransfer.setData('text/html', e.target.innerHTML);136 }137});138139sortableList.addEventListener('dragover', function(e) {140 e.preventDefault();141 const afterElement = getDragAfterElement(sortableList, e.clientY);142 const dragging = document.querySelector('.dragging');143144 if (afterElement == null) {145 sortableList.appendChild(dragging);146 } else {147 sortableList.insertBefore(dragging, afterElement);148 }149});150151function getDragAfterElement(container, y) {152 const draggableElements = [...container.querySelectorAll('li:not(.dragging)')];153154 return draggableElements.reduce((closest, child) => {155 const box = child.getBoundingClientRect();156 const offset = y - box.top - box.height / 2;157158 if (offset < 0 && offset > closest.offset) {159 return { offset: offset, element: child };160 } else {161 return closest;162 }163 }, { offset: Number.NEGATIVE_INFINITY }).element;164}
Output
// Output depends on drag and drop interaction
What's going on
Drag and drop enables interactive UI.
HTML5 Drag and Drop API
draggable: Make element draggable
dragstart: Drag begins
dragend: Drag ends
dragover: Over drop target
dragleave: Leave drop target
drop: Item dropped
Data Transfer
setData(): Set drag data
getData(): Get drop data
effectAllowed: Allowed effects
dropEffect: Visual feedback
Custom Implementation
Mouse events
Touch events
Position tracking
Constraints
Use Cases
File uploads
Sortable lists
Drag to reorder
Interactive games
Best Practices
Provide visual feedback
Handle touch events
Add constraints
Test accessibility