Simple tutorial for Drag and Drop in HTML5

Drag and Drop is a the basic feature needed when talking about the application handling Media or shuffling Data. This post is a simple tutorial for Drag and Drop in HTML5 with JavaScript.

Simple tutorial for Drag and Drop in HTML5

Drag and Drop is a the basic feature needed when talking about the application handling Media or shuffling Data.

Today we will look at the simple tutorial for Drag and Drop in HTML5.

If you are dealing with Media, then you will need Drop area (Dropzone) in application and in case of Data Shuffling, both Dragable elements and Dropzone both.

An element can be enabled to be dragged with dragable attribute to the element like as follows:

<div draggable="true" class="card">

With this attribute being present with the element, you can register the event handlers for following events:
HTML Drag and Drop API - Web APIs | MDN

  • drag
  • dragstart
  • dragend
  • dragenter
  • dragover
  • dragleave
  • dragexit
  • drop

As the element we mentioned above is dragable; you can listen for dragger and drop events on the target element. Like as follows in addition to above source:

<div class="draggable-items">
  <div class="row">
    <div class="col">
      <div class="card bg-light my-3" draggable="true">
        <div class="card-header">Light card title</div>
        <div class="card-body">
          <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<div class="row dropzones">
  <div class="col">
    <div class="my-3 p-3 border rounded dropzone">
      <span class="text-muted">Drop the cards here</span>

And the JS to make it work will go as follows:

const dropzones = document.querySelector('.dropzones');

let el = null;

  .addEventListener('dragstart', e => {
    el =

dropzones.addEventListener('dragover', (e) => {
dropzones.addEventListener('dragenter', (e) => {
  if ('dropzone')) {'solid-border');
dropzones.addEventListener('drop', (e) => {
  el = null;'solid-border');

dropzones.addEventListener('dragleave', (e) => {
  if ('dropzone')) {'solid-border');

The key thing to note is here is that to allow drag event to happen on the dropzone element, you need to capture dragover event and prevent the events’ default action by event.preventDefault()

Then in the drop event you can access the data transfer attribute from the event and take necessary action.

And For files, you need to capture dragenter, dragover, dragleave and drop events on dropzone element.

In case of files the drop event has files property in the dataTransfer property of event and then you can access the files in the similar way you would handle input type file

Following JS code will handle the file drops in a dropzone:

const events = [
  'dragover', // to allow drop
events.forEach(e => {
  fileDropZone.addEventListener(e, (ev) => {
    if (ev.type === 'dragenter') {
    if (ev.type === 'dragleave') {
    if(ev.type === 'drop') {
        .then(values => => {
          tag.setAttribute('class', 'border rounded img-preview');

const handleFiles = (_files)  => {
  const files =;
  return Promise.all( 

const generatePreviewData = (file) => {
  const fr = new FileReader();
  return new Promise((resolve, reject) => {
    fr.addEventListener('load', (e) => {
    fr.addEventListener('error', (e) => {

const imgForFile = (file) => {
  return generatePreviewData(file)
    .then((data) => {
      const img = document.createElement('img');
      img.src = data;
      img.height = 200;
      return img;

Here in the demo or example, asynchronous operation to generate the preview of the images. You can also use it to upload files to Backend.

For the image preview, we have used the code from previous post:

Generate instant previews for image upload - Time to Hack
Quick and Easy solution to generate preview of images upload in vanilla javascript in callback and Promise style.

⚠️ Attention

Thin dataTransfer

While setting dataTransfer item, keep this info as less as possible.

Why? As the events are propagated to the document root and if other delegated handlers are attached, the event processing might slow down.


Another key thing to notice is to preventDefault actions as the browser might react to file drops or link drops and result in unwanted behaviors.

Demo Code

Let me know through comments 💬 or on Twitter at @heypankaj_ and/or @time2hack

If you find this article helpful, please share it with others 🗣

Subscribe to the blog to receive new posts right to your inbox.

Hey There! You have made it this far.

Would you like to subscribe via email?