DevTips – Native Drag & Drop with HTML5


One of the things I like the most about WordPress is its plugin system–there's a lot you can do! For instance, you can download and install our new plugin, Nelio Content.

Native solutions are the best! Just a few weeks ago we were talking about vanilla JavaScript, remember? Why would you use a heavy third-party library when you can achieve the same results natively? Well, not the same results–native usually means faster and smoother. And I’m not the only one who likes simple native solutions: last week I read this amazing post (in Spanish) on how to implement a progress bar using CSS only, no JavaScript involved. Brilliant!

Today I’d like to talk about native Drag&Drop using HTML5. I know this is a functionality you’ll seldom use, but depending on the UI you’re creating, it might come quite handy. For instance, the Editorial Calendar included in Nelio Content makes an extensive use of such a feature:

Unscheduled Posts Section in the Editorial Calendar
Editorial Calendar in Nelio Content with several scheduled posts.

As you can imagine, rescheduling posts should be as simple as dragging and dropping them around the calendar, right? And that’s exactly what Nelio Content‘s calendar does! But how? How do you implement this? How do you specify which elements should move? How do you tell the browser which elements can receive a drop? Well, that’s what we’ll be talking about right now!

Drag & Drop Using jQuery UI

Before we talk about the HTML5 and JavaScript native solution, I thought it’d be a good idea to look at how jQuery UI tackles this problem, because that’s how Drag & Drop currently works in Nelio Content and it’s extremely simple to use. With jQuery UI, you simply need to use two different functions: draggable and droppable. The former is applied to the element we want to drag, and the latter is used to the elements in which we should be able to drop what we’re dragging. Let’s take a look at the following running example to have a better understanding of what I’m talking about:

See the Pen Drag&Drop using jQuery UI by David (@davilera) on CodePen.0

That’s pretty simple, isn’t it? There’s little to say about the HTML and CSS components of our tiny example, so let’s focus on the JavaScript. First, we start by making all items with the class item draggable. The function we call accepts an object with several properties but we’re only using one: the helper. By using helper:"clone", we’re basically telling jQuery UI that, when we start to drag an item, the “element” that we’ll be moving around will be a clone of the original item.

Next, we simply specify that all elements with the class day are droppable areas–that is, they can receive a drop event and respond to it as we please. In this particular example, we configured the droppable area as follows: first, we tell jQuery that we’ll be only accepting elements with the item class; then, we specify the class that a droppable area must have when we’re hovering it while dragging an element (so that we can highlight it and let the user know they can drop the element there); and finally we define the drop function, which tells our UI how to behave when we drop an element (in this case, we remove the dragged object from the original location to the area in which we dropped it).

Native Drag & Drop with HTML5 and JavaScript

A native Drag&Drop implementation using HTML5 and vanilla JavaScript is quite similar to that of jQuery UI (albeit slightly more complicated). Basically, we’ll have to follow the same exact steps we just took:

  1. Specify what can be dragged. That’s super simple–we only need to add the draggable="true" attribute in the element we want. Alternatively, you can do that in pure JavaScript too: item.setAttribute('draggable',true).
  2. Specify where can an element be dropped. We simply need to specify the ondrop callback of the droppable elements.

And that’s it! Here you have the native implementation:

See the Pen Native Drag&Drop with HTML5 by David (@davilera) on CodePen.0

“Hold on a sec, David. That’s way more complicated than what you’ve just explained.” Well, yes, you’re right: implementing a native D&D solution requires a few more lines of code than those required by jQuery UI, because some of the things that can be tweaked using a simple flag in jQuery, require a tiny function in vanilla JS. Let’s take a closer look:

  • The helper we’re dragging. Remember the helper option in jQuery UI? Well, we need something similar in HTML5. When we start to drag something, the callback ondragstart is called and it’s our responsibility to define the helper element (lines 9 and 10) and store the element we’re moving in a global variable (line 11).
  • Highlight droppable areas. To highlight the droppable areas when hovering them with the mouse, we need to use three low level events: ondragenter, ondragover, and ondragleave. With these, we can easily add or remove the highglight class as we please.

And that’s all! Indeed, native Drag & Drop is more verbose, but the final result is faster and feels more smooth. In this particular example you might not feel the difference, but if you’re running it on an old computer or if there’s plenty of rendered elements on the screen, there’s a huge difference.

Featured Image by Tetsuya Tomomatsu on Unsplash.

PoorMehGoodVery GoodAwesome! (2 votes, average: 5.00 out of 5)


He obtained his PhD in Computer Science at UPC. David leads the analysis and design of our services and the user support area. He's interested in a variety of areas, including conceptual modeling, virtual reality, and 3D digital printing. He contributes to the WordPress community by participating in meetups, seminars, and the WCEU.

Leave a Reply

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

I have read and agree to the Nelio Software Privacy Policy

Your personal data will be located on SiteGround and will be treated by Nelio Software with the sole purpose of publishing this comment here. The legitimation is carried out through your express consent. Contact us to access, rectify, limit, or delete your data.