Game With the HTML Drag and Drop API - Mboton Dev

Game With the HTML Drag and Drop API


Game With the HTML Drag and Drop API Mboton
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.

 <ul class="vehicles">
  <li>
    <!-- Fire Truck -->
    <!-- <code>img<code> elements don't need a <code>draggable<code> attribute like other elements -->
    <img id="fire-truck" alt="fire truck" src="https://cdn.glitch.com/20f985bd-431d-4807-857b-e966e015c91b%2Ftruck-clip-art-fire-truck4.png?1519011787956"/>
  </li>
  <li>
    <!-- Ambulance -->
    <img id="ambulance" alt="ambulance" src="https://cdn.glitch.com/20f985bd-431d-4807-857b-e966e015c91b%2Fambulance5.png?1519011787610">
  </li>
  <li>
    <!-- Car -->
    <img id="car" alt="car" src="https://cdn.glitch.com/20f985bd-431d-4807-857b-e966e015c91b%2Fcar-20clip-20art-1311497037_Vector_Clipart.png?1519011788408">
  </li>
  <li>
    <!-- Bike -->
    <img id="bike" alt="bicycle" src="https://cdn.glitch.com/20f985bd-431d-4807-857b-e966e015c91b%2Fbicycle-20clip-20art-bicycle3.png?1519011787816">
  </li>
</ul> 

Since images are draggable by default, you’ll see dragging any one of them creates a ghost image.
  • fire truck
  • ambulance
  • car
  • bicycle

 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’ll cover what the drag data and the drag effect is shortly


let dragged; // Keeps track of what's being dragged - we'll use this later! 

function onDragStart(event) {
  let target = event.target;
  if (target && target.nodeName === 'IMG') { // If target is an image
    dragged = target;
    event.dataTransfer.setData('text', target.id);
    event.dataTransfer.dropEffect = 'move';
    // Make it half transparent when it's being dragged
    event.target.style.opacity = .3;
  }
}

function onDragEnd(event) {
  if (event.target && event.target.nodeName === 'IMG') {
    // Reset the transparency
    event.target.style.opacity = ''; // Reset opacity when dragging ends 
    dragged = null; 
  }
}

// Adding event listeners
const vehicles = document.querySelector('.vehicles');
vehicles.addEventListener('dragstart', onDragStart);
vehicles.addEventListener('dragend', onDragEnd);

There are a couple of things happening in this code:

  1. 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.
  2. 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.
  3. 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:

WHATWG Specification

Working with HTML5 Drag-and-Drop - Pro HTML5 Programming, Chapter 9, by Jen Simmons
Accessible Drag and Drop Using WAI-ARIA - Accessibility considerations from Dev.Opera
Native HTML5 Drag and Drop - HTML5 Rocks tutorial
The HTML5 drag and drop disaster 

QuirksMode post with helpful context on the DnD module implementation
Game With the HTML Drag and Drop API Game With the HTML Drag and Drop API Reviewed by Mboton on March 10, 2018 Rating: 5

No comments:

Powered by Blogger.