Simple Drag and Drop With HTML Javascript – A 5 Minutes Tutorial

INTRODUCTION

EASY DRAG-AND-DROP

Welcome to a quick tutorial on how to do drag and drop with HTML and Javascript. Once upon a time in the dark ages of the Internet, implementing drag-and-drop on a website is a massive task that involves a lot of coding with 3rd party libraries. But ever since HTML5, it has been made a native feature of HTML and we no longer have to fight with digital dragons.

In the simplest design, a drag-and-drop mechanism in HTML and Javascript only requires:

  • Create a draggable element by adding the draggable property – <div id=”drag” draggable>Drag This</div>
  • Create a “dropzone” – <div id=”drop”>Drop Here</div>
  • Attach a drop listener in Javascript – document.getElementById(“drop”).addEventListener(“drop”, function(){ DO SOMETHING }).

But just how is this done exactly? There are still quite a number of events and stuff that you need to know – Which we will walk through in this tutorial. Read on for more examples!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

 

PREAMBLE

DOWNLOAD & NOTES

First, here is the download link to the example source code as promised.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

QUICK NOTES

There is nothing to install, so just download and unzip into a folder. If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

SECTION A

THE BASICS

All right, let us now get started with a very basic drag-and-drop example.

 

THE HTML

1a-basic.html
<div id="dragthis" draggable="true">DRAG THIS</div>
<div id="dropthis">DROP HERE</div>

In this very simple example, we only have 2 <div>:

  • <div id="dragthis"> is the draggable element. Yep, adding the draggable="true" attribute is all it takes to turn an element into draggable.
  • <div id="dropthis"> is the “drop zone”.

That’s it, sorry to guys who are looking for brain-damaging code.

 

 

THE CSS

1b-basic.css
#dragthis, #dropthis {
  width: 100%;
  padding: 10px;
  box-sizing: border-box;
  border: 1px solid #333;
  background: #eaeaea;
}
#dropthis {
  margin-top: 10px;
}
#dropthis.hint {
  background: #fea;
}
#dropthis.active {
  background: #ffd4d4;
}

The CSS is actually optional… These are just some cosmetics to make the demo look better. Just a quick note though:

  • #dropthis.hint is used to highlight the drop zone when the drag starts.
  • #dropthis.active is used to further highlight the drop zone the draggable element hovers over it.

 

THE JAVASCRIPT

1c-basic.js
window.addEventListener("load", function(){
  var draggable = document.getElementById("dragthis"),
      droppable = document.getElementById("dropthis");

  // DRAG START - YELLOW HIGHLIGHT DROPZONE
  draggable.addEventListener("dragstart", function () {
    droppable.classList.add("hint");
  });

  // DRAG ENTER - RED HIGHLIGHT DROPZONE
  droppable.addEventListener("dragenter", function () {
    droppable.classList.add("active");
  });

  // DRAG LEAVE - REMOVE RED HIGHLIGHT
  droppable.addEventListener("dragleave", function () {
    droppable.classList.remove("active");
  });

  // DRAG OVER - PREVENT THE DEFAULT "DROP", SO WE CAN DO OUR OWN
  droppable.addEventListener("dragover", function (evt) {
    evt.preventDefault();
  });

  // ON DROP - DO SOMETHING
  droppable.addEventListener("drop", function (evt) {
    evt.preventDefault();
    alert("DROPPED!");
  });

  // DRAG END - REMOVE ALL HIGHLIGHT
  draggable.addEventListener("dragend", function () {
    droppable.classList.remove("hint");
    droppable.classList.remove("active");
  });

  // NOT USED - WHEN DRAGGABLE IS BEING DRAGGED AROUND
  // draggable.addEventListener("drag", function (evt) {  });
});

The Javascript is probably the “most confusing” part. Not going to explain line-by-line, but to keep the long story short – We attach event listeners at the various “drag stages”  to create a useful application. This simple example practically does… nothing useful, and only highlights the possible drop zones by toggling CSS classes.

EventDescription
dragstartFired when the drag starts.
dragendFired when the drag stops.
dragAs the element is being dragged around.
dragenterWhen the mouse enters the boundaries of an element.
dragoverAs the element is being dragged over another element.
dragleaveWhen the mouse exits the boundaries of an element.
dropFired when the element is being dropped.

 

 

THE DEMO

DRAG THIS
DROP HERE

 

SECTION B

DRAG-AND-DROP SORTABLE LIST

The uses of drag-and-drop are very wide, and the above basic example may still leave people confused. So here it is, another example on how to create a sortable list using drag-and-drop.

 

THE HTML

2a-list.html
<ul id="sortlist">
  <li draggable="true">First</li>
  <li draggable="true">Second</li>
  <li draggable="true">Third</li>
  <li draggable="true">Forth</li>
  <li draggable="true">Fifth</li>
</ul>

Yep, nothing special here, just the usual unordered list <ul>. But remember that we add draggable="true" to the elements to make them draggable? Since we want to create a sortable list, we make all the list items <li> draggable.

 

THE CSS

2b-list.css
#sortlist {
  list-style: none;
  padding: 0;
  margin: 0;
}
#sortlist li {
  margin: 10px 5px;
  padding: 5px;
  border: 1px solid #333;
  background: #eaeaea;
}
#sortlist li.hint {
  background: #fea;
}
#sortlist li.active {
  background: #ffd4d4;
}

Cosmetics again – hint to highlight the possible drop zones, active when the draggable hovers over a drop zone.

 

 

THE SCRIPT

2c-list.js
window.addEventListener("load", function(){
  var items = document.querySelectorAll("#sortlist li"),
      dragged = null;

  for (let i of items) {
    // DRAG START - YELLOW HIGHLIGHT DROPZONE
    // Highlight all except the one being dragged
    i.addEventListener("dragstart", function () {
      dragged = this;
      for (let it of items) {
        if (it != dragged) { it.classList.add("hint"); }
      }
    });

    // DRAG ENTER - RED HIGHLIGHT DROPZONE
    i.addEventListener("dragenter", function () {
      if (this != dragged) { this.classList.add("active"); }
    });

    // DRAG LEAVE - REMOVE RED HIGHLIGHT
    i.addEventListener("dragleave", function () {
      this.classList.remove("active");
    });

    // DRAG OVER - PREVENT THE DEFAULT "DROP", SO WE CAN DO OUR OWN
    i.addEventListener("dragover", function (evt) {
      evt.preventDefault();
    });

    // ON DROP - DO SOMETHING
    i.addEventListener("drop", function (evt) {
      evt.preventDefault();
      if (this != dragged) {
        let all = document.querySelectorAll("#sortlist li"),
            draggedpos = 0, droppedpos = 0;
        for (let it=0; it<all.length; it++) {
          if (dragged == all[it]) { draggedpos = it; }
          if (this == all[it]) { droppedpos = it; }
        }
        if (draggedpos < droppedpos) {
          this.parentNode.insertBefore(dragged, this.nextSibling);
        } else {
          this.parentNode.insertBefore(dragged, this);
        }
      }
    });

    // DRAG END - REMOVE ALL HIGHLIGHT
    i.addEventListener("dragend", function () {
      for (let it of items) {
        it.classList.remove("hint");
        it.classList.remove("active");
      }
    });
  }
});

The Javascript looks like quite a handful, but it is practically almost the same as the above basic example.

  • Highlight possible drop zones when the drag starts.
  • Highlight the drop zone when draggable hovers over.
  • The only difference is when the drop happens. Basically, we use insertBefore() to move the dragged element; Effectively turning it into a sortable list.

 

 

THE DEMO

  • First
  • Second
  • Third
  • Forth
  • Fifth

 

EXTRA

USEFUL BITS & LINKS

That’s it for the example code, and here are some extras and links that you may find useful.

 

REACT, JQUERY, VUE DRAG-AND-DROP… EASIER!?

Many popular frameworks also provide various drag-and-drop mechanisms. But now that you know how all of these can be done easily in native HTML and Javascript, do they really make sense? Personally, I gave up on most third-party libraries.

While they do add some convenience, modern Javascript has kind of made many libraries redundant. Third-party libraries introduce loading bloat, dependency, and also takes a hit to the performance – You decide if some coding convenience is worth it in the long run.

 

LINK & REFERENCES

 

 

EXTRA

VIDEO TUTORIAL

For you guys who want more, here’s the video tutorial, and shameless self-promotion – Subscribe to the Code Boxx YouTube channel for more!

 

YOUTUBE TUTORIAL

 

INFOGRAPHIC CHEAT SHEET

Simple HTML Javascript Drag-and-Drop (click to enlarge)

 

CLOSING

WHAT NEXT?

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you to better understand how vanilla Javascript drag and drop works. If you have anything to add to this guide, please feel free to comment below. Good luck and happy coding!

2 thoughts on “Simple Drag and Drop With HTML Javascript – A 5 Minutes Tutorial”

  1. Hello, dear very good explanation, at the same time I have a query when the card is dragged in its container disappears, I appreciate you can answer that question.

    1. Fixed. A small bug in the “on drop” listener –
      1) Originally, it is if (evt.target != draggable.parentNode)
      2) The intention here is that we move the draggable element only if it is dropped into another container.
      3) But it is possible for the draggable element to be dropped into itself.
      4) The draggable.parentNode.removeChild(draggable); part works, remvoing the draggable element from the current container.
      5) The evt.target.appendChild(draggable); did not work and causes the draggable to dissappear.
      6) We now change the check to evt.target != draggable.parentNode && evt.target != draggabl to prevent that from happening.

Leave a Comment

Your email address will not be published. Required fields are marked *