Subscribe to my email list now at http://jauyeung.net/subscribe/
Follow me on Twitter at https://twitter.com/AuMayeung
Many more articles at https://medium.com/@hohanga
In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being submitted, changes in an element like resizing, or errors that happen when an app is running, etc.
We can assign event handlers to events so we can take perform an action when one is triggered. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we will look at the ondragstart
and ondrop
event handlers.
ondragstart event
The ondragstart
property of an HTML element lets us assign an event handler for the dragstart
event which is triggered when the user starts dragging an element or text selection. For example, if we want to tracking when an element has started to be dragged and when it’s dropped, we can write the following HTML code:
<p id='drag-start-tracker'>
</p>
<div id='drag-box' draggable="true">
</div>
<div id='drop-zone'>
</div>
In the code above, we have a p
element to show when something is dragged and the ID of the element that's being dragged. We have an element with the ID drag-box
that's being dragged. Below that, we have a div
with the ID drop-
zone that will accept any element that is being dragged to be dropped in it. Then we can add the following CSS to style the HTML elements we added above:
#drag-box {
width: 100px;
height: 100px;
background-color: red;
}
#drop-zone {
width: 200px;
height: 200px;
background-color: purple
}
We can see that drag-box
is red and drop-zone
is purple and that drop-zone
is bigger than drag-box
. Next, we can assign our own event handler function to the ondragstart
property for the DOM object representing the drag-box
element to track it when it’s being dragged and update our drag-start-tracker
p
element to show that drag-box
is being dragged with the following code:
const dragBox = document.getElementById('drag-box');
const dropZone = document.getElementById('drop-zone');
const dragStartTracker = document.getElementById('drag-start-tracker');
dragBox.ondragstart = (e) => {
dragStartTracker.innerHTML = `Element with ID ${e.target.id} is being dragged.`;
};
dragBox.ondragend = (e) => {
dragStartTracker.innerHTML = '';
dropZone.appendChild(e.srcElement);
};
In the code above, we can see that ‘Element with ID drag-box is being dragged’ when the drag-box
element is being dragged, and when we stop dragging the box and drop it into the drop-zone
element, we should see that the text disappears and the drag-box
element stays inside the drop-zone
element. How it works is that when we first start dragging the drag-box
element, the dragstart
event will be fired and the dragBox.ondragstart
will be called with the DragEvent
object passed in, which has the e.target.id
property that we reference to get the ID of the drag-box
element.
When we release the mouse button when the drag-box
is over the drop-zone
, the event handler that we assigned to the ondragend
event handler is called since the dragend
event is triggered by releasing the mouse button, ending the dragging of the drag-box
.
Inside the function, we have a DragEvent
object passed in when the function is called and we can use the srcElement
to get the DOM element object of the element being dragged, so we can use appendChild
method of the dropZone
object to append the drag-box
element, which is what we get with the srcElement
property to the drop-zone
element.
ondrop event
We can set the ondrop
property of a DOM element to handle the drop
event for the element. The drop
event is fired when an element or text selection is dropped into a valid drop target. For example, we can use it to make a div
element that can be dragged to 2 different boxes and use the ondrop
event handler to handle the dropping. First, we add the following HTML code to make our draggable div
element and 2 div
elements where we can drop the draggable div
element into the following code:
<div id='drag-box' draggable="true">
</div>
<div id='drop-zones'>
<div id='drop-zone'>
</div>
<div id='drop-zone-2'>
</div>
</div>
Then we can add some CSS code to style the div
elements with the following code:
#drag-box {
width: 100px;
height: 100px;
background-color: red;
}
#drop-zone {
width: 200px;
height: 200px;
background-color: purple
}
#drop-zone-2 {
width: 200px;
height: 200px;
background-color: green
}
#drop-zones {
display: flex;
}
In the code above, we make the drop-zone
div
elements side by side by add a div
with the ID drop-zones
to contain the 2 div
elements inside. We use the display: flex
CSS code to display drop-zone
and drop-zone-2
div
elements side by side. Then we change the background color of each div so we can distinguish them. Next, we add the JavaScript code to handle the dragging of the drag-box
div
elements and the dropping of it into either of the drop-zone
elements with the with ondrop
event handler that we define with the following code:
const dragBox = document.getElementById('drag-box');
dragBox.ondragstart = (e) => {
e
.dataTransfer
.setData('text/plain', event.target.id);
};
document.ondragover = (e) => {
e.preventDefault();
};
document.ondrop = (e) => {
const id = e
.dataTransfer
.getData('text');
e.srcElement.appendChild(document.getElementById(id));
}
The code above works by handling the ondragstart
event handler to get the ID of the element that’s being dragged. The ondragstart
handler is called when users start dragging the drag-box
div
. Inside the ondragstart
event handler function that we defined, we called the e.dataTransfer.setData
method to set the 'text'
attribute of the DataTransfer
object, which we need later when we’re dropping the drag-box
inside one of the drop-zone
or drop-zone-2
div
elements. It’s very important that we have:
document.ondragover = (e) => {
e.preventDefault();
};
This prevents the ondragover
event handler from handling the event since once it’s handled with that event handler, then the drop
event won’t be fired, and our ondrop
event handler won’t be run. With that out of the way, we can define our ondrop
event handler and then assign it to the document.ondrop
property to handle the document
’s drop
event.
The event handler function has an e
parameter which is a DragEvent
object, which has some useful properties that we can use to handle the dropping of our drag-box
element. Inside that event handler, we get the ID of the element that we’re dragging by calling the e.dataTransfer.getData
method with the 'text'
string to get the ID of the element that we’re dragging.
Then we can use the srcElement
property of the e
object to get the DOM element of which our drag-box
div
is being dropped and call appendChild
on it with the document.getElementById(id)
argument, where id
should be 'drag-box'
since that’s what should return from e.dataTransfer.getData(‘text’);
since we set the ID of the drag-box
element in the dragBox.ondragstart
event handler.
Wrap Up
The ondragstart
and ondrop
properties are very useful for making drag and drop features in our web page. The ondragstart
property lets us assign an event handler for the dragstart
event, which is triggered when the user starts dragging an element or text selection. We can set the ondrop
property of a DOM element to handle the drop
event for the element. The drop
event is fired when an element or text selection is dropped into a valid drop target.
Note that we have made set an event handler function for the ondragover
property of document
and call e.preventDefault()
inside the function to prevent the ondragover
event handler from handling the dragover
event, which stops the drop
event from triggering. With that out of the way, we can assign an event handler to the ondrop
property to append the draggable element as a child to the drop target element.