Drag and Drop Using Pure Javascript

Posted By Jayant Singh Parmar | 26-Jul-2018

In this blog, we are going to look at javascript drag and drop events and for that, we are going to create a small application with a little HTML, CSS and javascript. In this application we are going to be able to grab an image and when we hover over any of the empty boxes it gets a little bit darker and it gets a different kind of border and we can drop it in any of these boxes. Now obviously this by itself is not really a full application but I am going to show you how to implement this type of UI so you could use it in anything where you want this kind of effect.

Alright so let's go ahead and get started. I am using VS Code, you can use whatever you like. So I am having a very basic project setup where I have three following files.

  • index.html : Main HTML page
  • style.css : Main stylesheet
  • main.js : Main javascript file

So for creating our HTML boilerplate, I am using emmet which is a very good VS Code extension. I highly recommend emmet if you use VS Code because it provides an ultrafast HTML & CSS workflow. HTML for this project is going to be very simple, I have five boxes(div) and each has a CSS class "empty" and one box is filled(with image) has a CSS class "filled"  and is placed inside an empty box and for that I am adding the following markup to our index.html file.

        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <meta http-equiv="X-UA-Compatible" content="ie=edge">
                <title>Drag & Drop Using Pure Javascript</title>
                <link rel="stylesheet" href="style.css">
            </head>
            <body>
                <div class="empty">
                    <div class="fill" draggable="true"> </div>
                </div>
                <div class="empty"></div>
                <div class="empty"></div>
                <div class="empty"></div>
                <div class="empty"></div>
                <script src="main.js"></script>
            </body>
        </html>
    

I have set the HTML-5 property "draggable" to true on the div having the "fill" class otherwise we will not be able to drag it and that's it for our HTML. So next we will move on to our style.css and add the following code to it. 

        body {
            background: darksalmon;
        }
          
        .fill {
            background-image: url('https://source.unsplash.com/random/150x150');
            position: relative;
            height: 150px;
            width: 150px;
            top: 5px;
            left: 5px;
            cursor: pointer;
        }
          
        .hold {
            border: solid 5px #ccc;
        }
          
        .empty {
            display: inline-block;
            height: 160px;
            width: 160px;
            margin: 10px;
            border: solid 3px salmon;
            background: white;
        }
          
        .hovered {
            background: #f4f4f4;
            border-style: dashed;
        }
    

For the "fill" class I am using an image as background and for that, I am using an API from  unsplash.com which give you a random image every time you reload the page.

Alright, now we can start on the javascript. Basically, we have two elements to work with the filled box and the empty ones. First of all, we have to declare two variables as shown below.

        const fill = document.querySelector('.fill');
        const empties = document.querySelectorAll('.empty');
    

I have created two variables "fill" and "empties" for the filled and empty boxes(div) respectively. Now we will add the event listeners for both variables.

        // Fill listeners
        fill.addEventListener('dragstart', dragStart);
        fill.addEventListener('dragend', dragEnd);

        // Loop through empty boxes and add listeners
        for (const empty of empties) {
            empty.addEventListener('dragover', dragOver);
            empty.addEventListener('dragenter', dragEnter);
            empty.addEventListener('dragleave', dragLeave);
            empty.addEventListener('drop', dragDrop);
        }
    

Now we will add the drag functions to handle the events for the "fill" variable. 

        // Drag Functions
        function dragStart() {
            this.className += ' hold';
            setTimeout(() => (this.className = 'invisible'), 0);
        }

        function dragEnd() {
            this.className = 'fill';
        }
    

dragStart( ) : called when we grab the image(filled box) and drag it.

dragEnd( ): called when we leave the image(filled box).

Now we will add the drag functions for the "empties" variable. 

        function dragOver(e) {
            e.preventDefault();
        }

        function dragEnter(e) {
            e.preventDefault();
            this.className += ' hovered';
        }

        function dragLeave() {
            this.className = 'empty';
        }

        function dragDrop() {
            this.className = 'empty';
            this.append(fill);
        }
    

Now our main.js file should look like as shown below. 

        const fill = document.querySelector('.fill');
        const empties = document.querySelectorAll('.empty');

        // Fill listeners
        fill.addEventListener('dragstart', dragStart);
        fill.addEventListener('dragend', dragEnd);

        // Loop through empty boxes and add listeners
        for (const empty of empties) {
            empty.addEventListener('dragover', dragOver);
            empty.addEventListener('dragenter', dragEnter);
            empty.addEventListener('dragleave', dragLeave);
            empty.addEventListener('drop', dragDrop);
        }

        // Drag Functions
        function dragStart() {
            this.className += ' hold';
            setTimeout(() => (this.className = 'invisible'), 0);
        }

        function dragEnd() {
            this.className = 'fill';
        }

        function dragOver(e) {
            e.preventDefault();
        }

        function dragEnter(e) {
            e.preventDefault();
            this.className += ' hovered';
        }

        function dragLeave() {
            this.className = 'empty';
        }

        function dragDrop() {
            this.className = 'empty';
            this.append(fill);
        }
    

Now you can try it, just reload the page and grab the image and as you hover over the boxes you will see the hover effect and when you drop, the image will be placed inside another box. You can also check it under the elements tab in your browser's developer console. So basically we are moving in around the DOM and this all is possible with the drag events and HTML-5 draggable property.

Hopefully, this explains drag and drop to you guys. Obviously, this is not a real application but you can use it in the UI of your application. For reference you can download the source code here.  

Request for Proposal

Recaptcha is required.

Sending message..