freecoding.school100% FREE · NO SIGNUP
Input HarborISSUE #29 of 46

drag and drop · draggable · datatransfer

FormaVSCaptain Invalid Input
Forma saysThe Drag and Drop API makes elements draggable and lets drop zones receive them via dataTransfer.

Set draggable="true" on an element, then handle the events: dragstart (stash data in e.dataTransfer), dragover (must call e.preventDefault() to allow a drop), and drop (read the data back).

The crucial gotcha: a drop zone won't accept anything unless its dragover handler calls preventDefault(). That single line is why most "drag and drop doesn't work" bugs happen.

Power-ups you unlock

Captain Invalid Input attacks — common mistakes

Boss battleMake a chip draggable into a box. On drop, move the chip inside the box and highlight the box during dragover.

Example code

<!doctype html>
<html><head><meta charset="utf-8">
<style>
  body{background:#06040d;color:#e6e0ff;font-family:sans-serif;padding:20px}
  #chip{display:inline-block;padding:8px 14px;background:#b388ff;color:#06040d;border-radius:4px;cursor:grab}
  #zone{margin-top:16px;min-height:80px;border:2px dashed #2a1d4a;border-radius:6px;padding:14px}
  #zone.hot{border-color:#b388ff;background:rgba(179,136,255,.08)}
</style></head>
<body>
  <div id="chip" draggable="true">drag me</div>
  <div id="zone">drop here</div>
  <script>
    const chip=document.getElementById('chip'), zone=document.getElementById('zone');
    chip.addEventListener('dragstart', e => e.dataTransfer.setData('text/plain','chip'));
    zone.addEventListener('dragover', e => { e.preventDefault(); zone.classList.add('hot'); });
    zone.addEventListener('dragleave', () => zone.classList.remove('hot'));
    zone.addEventListener('drop', e => { e.preventDefault(); zone.classList.remove('hot'); zone.appendChild(chip); });
  </script>
</body></html>
▶ Open the interactive comic issue
‹ Geolocation · Lat · Lon · PermissionWeb Storage · LocalStorage · SessionStorage ›