How To Handle Drag and Drop Event In JavaScript

Drag and drop is a user interface for transferring data between a "drag source" and "drop target" that may be in same application or in different applications. Any document element that has the HTML draggable attribute is a drag source and the the element where the HTML element dropped is drop target. In other words, drag and drop allows the user to click and hold the mouse button down over an element, drag it to another location, and release the mouse button to drop the element there. This techniques allow elements to be dragged and "dropped" within a web page or other. In this post I am going to describe the methods and examples to handle drag and drop event in JavaScript.

Drag and drop is always event based and JavaScript involves two sets of events, the first one is fired on drag source and another is fired on the drop target. All drag and drop event handlers are passed an event object that is like a mouse event object, with the addition of dataTransfer property. This property refers to a DataTransfer object that defines the methods and properties of the drag and drop application.

Here is a simple example of drag and drop event, where the text can be dragged into a textbox.

Drag This text on Textbox

You can use the following HTML code to display this example of drag and drop event.

<form>
<span draggable="true" ondragstart="event.dataTransfer.setData('text/plain','This text was dragged')">Drag This text on Textbox</span>
<input type=text></input>
<button type=reset>Clear</button>
</form>

Drag and drop operations are performed in different steps, the first of them is to set HTML elements attribute draggable. Only after setting elements attribute draggable browser allows you to drag any elements. You can make HTML elements draggable with adding attribute [draggable="true"] as the following.
<div draggable="true">This text is draggable</div>

Different Drag and Drop Events


A number of events are fired during various stages of the drag and drop operation. When the user begins a mouse drag over a drag source, the browser fires a dragstart event on the element instead of selecting the element content. After that drag event fires on the element continuously while dragging element then fired drop event while dropping on drop target. The different events fired during drag and drop operation on an element are given below.

dragstart

This event is fired on an element when a drag is started. The event handler for dragstart event should call dataTransfer.setData() to specify the data that the drag source is making available. You can also set dataTransfer.effectAllowed to specify which of the "move", "copy" and "link" transfer operations are supported and you can also call dataTransfer.setDragImage() to specify an image or document element to be used as the visual representation of the drag.


Here is a simple digital clock created on the post "How To Create a Digital Clock in JavaScript?", where the time displayed on the clock can be dragged to the textbox.



The following JavaScript and HTML code were used to drag clock time to the textbox.
<script>
clock.ondragstart=function(event){
var icon=new Image();
icon.src="clock.ico";
var event=event||window.event;
var dt=event.dataTransfer;
dt.setData("text/plain", "The Time is : "+clock.innerHTML+" Now.");
dt.effectAllowed="copy";
if(dt.setDragImage)dt.setDragImage(icon,0,0);
};
</script>

drag

While the drag progresses, the browser fires drag events on the drag source. You can add event handlers, if you want to update the drag image or alter the data being set, but it is not generally to register drag event handlers.

dragenter

This event is fired when the mouse enters an element while a drag is occurring.

dragover

This event is fired each time the mouse pointer moves as it moves across an element when a drag is occurring.

dragleave 

This event is fired when the mouse leaves an element while a drag is occurring.

dragend

This event is fired at the source of the drag when the drag operation is complete.

drop

Drop event is fired after dragend event is fired. If  the drag source supports a "move" operation, should check dataTransfer.dropEffect to see if a move operation was actually performed. You can also use getData method to retrieve the data again.
<script>
clock.ondrop=function(event){
var event=event||window.event;
var dt=event.dataTransfer;
var getdata=dt.getData("text/plain");
event.clock.innerHTML=getdata;
dt.dropEffect="copy";
event.preventDefault();
};
</script>

Example Of Handling Drag and Drop Events


Here is another example of drag and drop event, where the list items of unordered list can be dragged and dropped into another box.

Drag Source
  • First Item
  • Second Item
  • Third Item
  • Fourth Item
Drop Target


    The CSS, HTML and JavaScript code used in this example are given below. 

    CSS Code:

    .box{width:300px;}
    #dragsource{float:left;left:25px;}
    #droptarget{float:right;right:25px;}
    ul{margin:0px;padding:0px;width:140px;height:305px;border:2px solid green;text-align:center;}
    ul>li{width:80px;height:30px;border:1px dotted brown;list-style:none;margin:20px; padding:10px;}

    HTML Code:

    <div class="box" >
    <ul id="dragsource">
    <li id="item1" draggable="true">First Item</li>
    <li id="item2" draggable="true">Second Item</li>
    <li id="item3" draggable="true">Third Item</li>
    <li id="item4" draggable="true">Fourth Item</li>
    </ul>
    <ul id="droptarget"></ul>
    </div>

    JavaScript Code:

    <script>
    window.onload=function(){
    var target1=document.getElementById("droptarget");

    var list=document.querySelectorAll("#dragsource li");
    for(i=0;i<list.length;i++){
    list[i].draggable=true;
    list[i].ondragstart=function(event){
    var event=event||window.event;
    var dt=event.dataTransfer;
    dt.setData("text", event.target.id);
    dt.effectAllowed="move";
    };}

    target1.ondragover=function(event) {
    var event=event||window.event;
    event.preventDefault();
    };

    target1.ondrop=function(event) {
    var event=event||window.event;
    var dt=event.dataTransfer;
    event.preventDefault();
    var data = dt.getData("text");
    target1.appendChild(document.getElementById(data));
    };
    };
    </script>