Game With the HTML Drag and Drop API

HTML5 was Drag and Drop < we’ll refer to it as DnD in this article > which brought native DnD support to the browser, making it easier for developers to implement this interactive feature into applications. The amazing thing that happens when features become easier to implement is that people start making all kinds of silly, impractical things with it, like the one we’re making today: a parking game HTML !

Requires only a few things to work

Something to drag
Somewhere to drop
JavaScript event handlers on the target to tell the browser it can drop
We’re going to start by creating our draggables.

Dragging

Both <img> and <a> elements are draggable by default. If you want to drag a different element, you'll need to set the draggable attribute to true.

We’ll start with the HTML that sets up the images for our four vehicles: fire truck, ambulance, car and bicycle.

Since images are draggable by default, you’ll see dragging any one of them creates a ghost image.

Just adding a draggable attribute to an element that’s not an image or link is really all you need to make an element draggable in most browsers. To make elements draggable in all browsers, you need to define some event handlers. They are also useful for adding extra functionality like a border if an element is being dragged around or a sound if it stops being dragged. For these, you’re going to need some drag event handlers, so let’s look at those.

Drag Events

dragstart - Triggered as soon as we start dragging. This is where we can define the drag data and the drag effect.

dragend - Triggered when a draggable element is dropped. This event is generally fired right after the drop zone’s drop event.

We are defining the drag data. Each drag event has a property called dataTransfer that stores the event's data. You can use the setData(type, data) method to add a dragged item to the drag data. We’re storing the dragged image’s ID as type 'text' in line 7.

We’re storing the element being dragged in a global variable. I know, I know. Global is dangerous for scoping but here’s why we do it: although you can store the dragged item using setData, you can’t retrieve it using event.dataTransfer.getData() in all browsers (except Firefox) because the drag data is protected mode. You can read more about it here. I wanted to mention defining the drag data just so you know about it.

We’re setting the dropEffect to move. The dropEffect property is used to control the feedback the user is given during a drag and drop operation. For example, it changes which cursor the browser displays while dragging. There are three effects: copy, move and link.

copy- Indicates that the data being dragged will be copied from its source to the drop location.move- Indicates that the data being dragged will be moved.link- Indicates that some form of relationship will be created between the source and drop locations.

Now we have draggable vehicles but nowhere to drop them:

There are lots of ways this could be improved:

Auto-generate the HTML for the rules list from the parkingRules object!

Add some sound effects!

Add ability to drag back vehicles to original point without a page refresh.

All those pesky global variables.

But I’ll let you handle that.

If you’re interested in learning more about the DnD API and some critiques of it, here’s some good reading: