Drag and Drop Using Native Javascript 01

Video Tutorial

Overview

A lot of Web developers (Front End) get very confused about how drag and drop system works how to actually implement a flexible drag and drop effects well, in this tutorial we are gonna go through making a reliable drag and drop mechanism using native Javascript (No Libraries are needed) we are going to implement the whole app on CodePen so no further Setup is needed, all you need to do is Relax, Grab a Cube of Coffe and Enjoy Coding.

App Structure

We are going to have two panels, where the left items panel gonna hold the todo items that you can drag and drop the TODO Items Container in order to make those items applicable, the todos container will have the snap functionality where you just drag and hover the target item and you will get hints where the item should be placed..

So here is how the app structure we are going to work on

<div class="container">
  <div id="items-container" class="base-container">
    <div class="header">Items</div>
    <div class="todo-item">
      TODO Item
    </div>
  </div>
  <div id="todos-container" class="base-container">
    <div class="header">TODO</div>
  </div>
</div>

Also, the CSS Style that you may need to use for your own apps.

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row; 
  justify-content: space-around;
  align-items: center;
}

.base-container {
  min-width: 300px;
  min-height: 400px;
  //border: 1px solid rgba(15, 15, 15, 0.2);
  box-shadow: 0px 0px 20px 2px rgba(15, 15, 15, 0.2);
  padding: 25px;
}

.header {
  width: 100%;
  font-family: Oxygen, sans-serif;
  font-size: 22px;
  text-align: center;
}

.no-todo-container {
  border: 1px solid rgba(15, 15, 15, 0.2);
  box-shadow: 0px 0px 5px 10px rgba(15, 15, 15, 0.2);
} 

.todo-container {
  border: 1px solid rgba(15, 15, 15, 0.2);
  box-shadow: 0px 0px 5px 10px rgba(15, 15, 15, 0.2);
}

.todo-item {
  //border-bottom: 1px solid ;
  width: 300px;
  height: 20px;
  position: absolute;
  background-color: #F44336;
  color: #FFFFFF;
  font-family: Oxygen, sans-serif;
  font-size: 20px;
  padding: 7px;
  margin: 10px 0 10px 0;
  box-shadow: inset 1px 1px 10px 0 rgba(15, 15, 15, 0.2);
  border-radius: 3px;
  cursor: pointer;
}

.snap {
  width: 301px;
  height: 30px;
  margin-top: 5px;
  margin-bottom: 5px;
}

.over {
  background-color: rgba(15, 15, 15, 0.2);
  border: 2px solid #F44336;
  border-radius: 5px;
}

Let’s Start

First, we need reference both the items and todos container as well as the todo item(s) using native js

let itemsContainer = document.getElementById("items-container");

let todosContainer = document.getElementById("todos-container");

let todoItems = document.getElementsByClassName("todo-item");

Since we are going to work with multiple todo items instead of one, we need to loop through each item and handle mouse dragging specifically under the item.

Actually to drag an element using javascript you need to handle three important steps, first, handle mouse click under the element (mouse down) then, change item position and make it follow the mouse cursor while the mouse button is down and finally handle mouse button up which basically means stop moving.

we are going to create separate function handlers for those events to make things easier.

//Loop through all Todo Items (Handle all Todo Items Dragging)
for(let i = 0; i < todoItems.length; i++) {
  let item = todoItems[i];
  //Mouse Button Down
  item.addEventListener("mousedown", (e) => { onMouseDown(e, item); });
  //Mouse Move (Under the Page Body since mouse moves right there)
  document.body.addEventListener("mousemove", (e) => {
      onMouseMove(e, item);
  });
  //Mouse Up 
  item.addEventListener("mouseup", (e) => {
    onMouseUp(e, item);
  });
}

for the mouse down handler, we are going to change the item background color to make it more user-friendly and revert it back to the original color on mouse up.

//Mouse Down
function onMouseDown(e, item) {
  isMouseDown = true;

  mouseOffset = {x: item.offsetLeft - e.clientX, y: item.offsetTop - e.clientY};

  item.style.backgroundColor = "#E57373";
}
//Mouse Up 
function onMouseUp(e, item) {
  isMouseDown = false;
  item.style.backgroundColor = "#F44336";
}

As you can see we can track whether the mouse button is down or no using a global bool variable that we set on mouse down and up events, also we are keeping track of the mouse offset which basically the mouse cursor position when we click the todo item being substracted from the item offset (left and top).

Now the Important part is handling Mouse Movement, well this is very since all you need to do is make the item position the same as the mouse position while the mouse is holding the todo item, remember that you need to set the todo item position to absolute in order to be able to move it around the page.

function onMouseMove(e, item) {
  e.preventDefault(); ///< Stops the Default Element Bahiavor 
  if(isMouseDown) {
    //Move Item only when mouse is down 
    item.style.left = e.clientX + mouseOffset.x + "px";
    item.style.top = e.clientY + mouseOffset.y + "px";
    //Concatinating Numbers with Strings is Javascript gives you a String
  }
}

Now if you can try to move the Todo Item, you should get a very smooth dragging transition.

What’s Next

So this is Only the First Part of the Tutorial, in the Next one we are going to create the dropping effect with the ability to snap it to the right position

No Comments Yet