What needs to be kept in mind when using this API?
Before we get into this API, let’s discuss the minor things that we must keep in mind before using it. This will prevent us from falling into various pitfalls.
-
While performing the events related to drag and drop, we have to explicitly disable the other events of the DOM like onMouseDown, onMouseUp, onMouseOver, etc., as these events restrict the drag and drop event to happen.
- Whenever we drag an element, we have to use the data transfer object that comes with the drag and drop API of HTML. It holds the data and other information of the particular draggable element, and we can use this information when we drop the element. So a data transfer object holds the state of data of an element that we are dragging.
The above two points will be clear when implementing each topic in our primary drag and drop application.
Drag/Drop Events
There are many events and event handlers in this API. Using these events, we can control the entire Drag and Drop lifecycle. The Drag and Drop lifecycle of an element is nothing but the whole phase, which starts when we grab an element, moving it along the way and finally dropping it inside a container. For example, a dragstart event occurs when we grab an element with a mouse.
Let’s examine all the events and event handlers associated with it:
- drag: This event occurs when we are dragging an element, and we can handle this event by specifying the ondrag event handler inside an element as an attribute. The value to this attribute will be a function that gets invoked when this event is fired.
- dragend: This event occurs when we stop dragging an element (drag operation ends), such as releasing a mouse button or hitting the ESC key. We can handle this event by specifying the ondragend event handler inside an element as an attribute.
- dragenter: This event occurs when the element enters a valid drop container or target. And of course, we can handle it using an ondragenter handler.
- dragleave: This event occurs when the element leaves a valid drop container or target. The associated event handler is ondragleave.
- dragover: This event occurs when we drag an element over a valid droppable container or target. This event is fired every few hundred milliseconds. ondragover is the associated event handler for this.
- dragstart: This event occurs when the user starts dragging an item. The moment when an element is grabbed. ondragstart is the associated event handler.
- drop: This event occurs when the element is dropped into a droppable target container. ondrop is the associated event handler.
Drag/Drop Interfaces
There are four major HTML Drag and Drop interfaces, namely DragEvent, DataTransfer, DataTransferItem and DataTransferItemList.
-
DragEvent: The DragEvent interface is a DOM event initiated when a user puts a mouse pointer and starts dragging the element. This interface provides an object that is very useful to us as we can utilize it to add drag and drop functionality.
-
DataTransfer: The DataTransfer object is used to hold the data dragged during a drag and drop operation. This is by far the most important one.
-
DataTransferItem: The DataTransfer object contains the list of drag data items, whereas the DataTransferItem object represents one drag data item.
-
DataTransferItemList: The DataTransferItemList object is a list of DataTransferItem objects representing items being dragged. During a drag operation, each DragEvent has a dataTransfer property, and that property is a DataTransferItemList.
Understanding By Example
We’ll make a simple Drag and Drop application where we drag and drop the image from one container to another by using the above concepts.
The application looks something like this:
Let’s write some HTML code for this:
<body>
<div class="drop-box">
<div
class="draggable-element"
id="drag-me"
></div>
</div>
<div
class="drop-box"
></div>
<div
class="drop-box"
></div>
</body>
Let’s style the HTML code using CSS:
<style>
body {
background-color: rgb(238, 199, 185);
display: flex;
justify-content: center;
align-items: center;
}
.draggable-element {
background-image: url("https://source.unsplash.com/145x145/?person");
position: relative;
top: 7px;
left: 5px;
height: 145px;
width: 145px;
/* By setting a cursor pointer you'll get the essence of dragging something. */
cursor: pointer;
}
.drop-box {
display: inline-block;
height: 155px;
width: 155px;
margin: 10px;
background-color: white;
border: 2px solid black;
}
</style>
We’ve taken a random image from https://source.unsplash.com. But you can choose whichever image you want.
After styling our HTML, we have to implement drag and drop functionality so that we can drag the image to one of the containers.
For making any element draggable, we have to explicitly provide an attribute 'draggable' to the corresponding element and set its value to true as, by default, it is false.
<div
class="draggable-element"
draggable="true"
id="drag-me"
></div>
We have to provide an event handler ondragstart as an attribute to this element to set or store the data in the dataTransfer object via invoking our function dragIt().
<div
class="draggable-element"
draggable="true"
ondragstart="dragIt(event)"
id="drag-me"
></div>
Implementation of dragIt() function:
const dragIt = (event) => {
event.dataTransfer.setData("text", event.target.id);
};
This function takes a DOM event object as a parameter. This event object has all the necessary information about the element, such as its ID.
We have set the data associated with this element, such as its id, to the dataTransfer object using the setData() function. setData() set the data for a given type. If data for the type does not exist, it is added at the end, such that the last item in the types list will be the new format. If data for the type already exists, the existing data is replaced in the same position.
We have made an element draggable, now let’s make a container droppable so that we can drop this element into it:
<div
class="drop-box"
ondragover="allowDrop(event)"
></div>
To make a container droppable, we have to disable the default onmouse events of the target element where we are dropping (This is the point we have to keep in mind, as I mentioned earlier).
So to make the container droppable, we use the ondragover attribute as this event handler handles the event when the element is dragged over the target container.
We pass in a function allowDrop() which allows the element to be dropped inside the target container.
const allowDrop = (event) => {
event.preventDefault();
};
event.preventDefault() prevents the default mouse events and allows the elements to be dropped on it.
Just making the container droppable doesn’t mean we can place an element inside of it. For that, we have to append the element as a child inside the container. So, we have to append the element inside of it, and the best time to do that is when we drop an element. So we use the ondrop event handler as a drop event is taking place.
<div
class="drop-box"
ondragover="allowDrop(event)"
ondrop="dropIt(event)"
></div>
This event handler takes the dropIt() function as its value, invoking the element as its child.
const dropIt = (event) => {
let data = event.dataTransfer.getData("text");
event.target.append(document.getElementById(data));
};
You can also try this code with Online Javascript Compiler
Run Code
Now it’s done. We’ve made a drag and drop application. You can drag and drop it in one of the three containers.
The image is different from the one given above, as every time we reload the page, we get a different image as we have used a random image from source.unsplash.com.
Entire code at one glance:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Drag and Drop API</title>
<style>
body {
background-color: rgb(238, 199, 185);
display: flex;
justify-content: center;
align-items: center;
}
.draggable-element {
background-image: url("https://source.unsplash.com/145x145/?person");
position: relative;
top: 7px;
left: 5px;
height: 145px;
width: 145px;
/* By setting a cursor pointer you'll get the essence of dragging something. */
cursor: pointer;
}
.drop-box {
display: inline-block;
height: 155px;
width: 155px;
margin: 10px;
background-color: white;
border: 2px solid black;
}
</style>
</head>
<body>
<div class="drop-box" ondragover="allowDrop(event)" ondrop="dropIt(event)">
<!-- For making any element draggable, we have to explicitly provide an attribute 'draggable' to the corresponding element and set its value to true as by default it is set to false. -->
<div
class="draggable-element"
draggable="true"
ondragstart="dragIt(event)"
id="drag-me"
></div>
</div>
<div
class="drop-box"
ondragover="allowDrop(event)"
ondrop="dropIt(event)"
></div>
<div
class="drop-box"
ondragover="allowDrop(event)"
ondrop="dropIt(event)"
></div>
</body>
<script>
const dragIt = (event) => {
event.dataTransfer.setData("text", event.target.id);
};
const allowDrop = (event) => {
event.preventDefault();
};
const dropIt = (event) => {
let data = event.dataTransfer.getData("text");
event.target.append(document.getElementById(data));
};
</script>
</html>
Frequently asked questions
Q1. Why a container doesn’t allow elements to be dropped in it?
Various on mouse events are happening on the target/destination container by default, which restricts the drop event when we try to drop an element. To prevent this, we need to specify event.preventDefault() in our handler function to stop these default events.
Q2. What is the DataTransfer object?
Whenever we drag an element, we have to use the data transfer object that comes with the drag and drop API of HTML. It holds the data and other information of the particular draggable element, and we can use this information when we drop the element. So a data transfer object holds the state of data of an element that we are dragging.
Q3. Which event is fired as the mouse is moving over an element when a drag is occurring?
The dragover event is fired as the mouse is moving over an element when a drag is occurring. Much of the time, the operation during a listener will be the same as the dragenter event. When a draggable element enters a drop target, then a dragenter event has occurred. A dragleave event occurs when it leaves the valid drop target. Whenever a user starts to drag an element, dragstart is fired.
Key takeaways
To summarize this, we started with a brief introduction of the topic and got to know the motivation behind using the Drag and Drop feature and then we explored all the core concepts related to Drag and Drop API. Finally, we made a simple Drag and Drop application using all the necessary concepts of Drag and Drop.
So, it is not the end of the road here; way more things are present in this API. Just expand your domain and explore all about it, as learning has no endpoint. Keep a closer eye on our future blogs as they may prove helpful to you.