Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make drag and drop using vanilla javascript?

I have written a code for a drag and drop using vanilla javascript. When I pick the first div, it does move to last automatically while I was trying to move next.

I don't want to use the jquery library.

What I tried is I created the main div that acts as a container so that inside of that container each div can be moved easily

I have attached what I tried, but I don't understand why this is happening.

const draggables = document.querySelectorAll('.draggable')
const containers = document.querySelectorAll('.mainContainer')

draggables.forEach(draggable => {
  draggable.addEventListener('dragstart', () => {
    draggable.classList.add('dragging')
  })

  draggable.addEventListener('dragend', () => {
    draggable.classList.remove('dragging')
  })
})

containers.forEach(container => {
  container.addEventListener('dragover', e => {
    e.preventDefault()
    const afterElement = getDragAfterElement(container, e.clientY)
    const draggable = document.querySelector('.dragging')
    if (afterElement == null) {
      container.appendChild(draggable)
    } else {
      container.insertBefore(draggable, afterElement)
    }
  })
})

function getDragAfterElement(container, y) {
  const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]

  return draggableElements.reduce((closest, child) => {
    const box = child.getBoundingClientRect()
    const offset = y - box.top - box.height / 2
    if (offset < 0 && offset > closest.offset) {
      return { offset: offset, element: child }
    } else {
      return closest
    }
  }, { offset: Number.NEGATIVE_INFINITY }).element
}
body {
  font-family: sans-serif;
}

.mainContainer {
  padding: 6px 0;
  width: 100%;
}

.draggable {
  cursor: move;

  display: inline-block;
  margin: 0 6px;
  z-index: 1;

  color: #fff;
  background-color: #087ee5;
  border: 1px solid #0675d6;
  border-radius: 4px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  text-align: center;
  max-width: 300px;
  min-width: 30px;
  border-collapse: separate;
  vertical-align: middle;
  padding-left: 7px;
  padding-right: 7px;
  padding-top: 10px;
  padding-bottom: 10px;
}

.draggable.dragging {
  opacity: 0.5;
}
<div class="mainContainer">
      <p class="draggable" draggable="true">MOVE 1</p>
      <p class="draggable" draggable="true">MOVE 2</p>
      <p class="draggable" draggable="true">MOVE 3</p>
      <p class="draggable" draggable="true">MOVE 4</p>
    </div>
like image 777
Parth Tiwari Avatar asked Jan 22 '21 20:01

Parth Tiwari


1 Answers

Add an event listener for the dragables on mouseover. check if the dragable is already in your hand. if not than append the Node of the dragable in your hand after the Node with mouseover

change the position of the dragged element to absolute and define its position x & y through top and left

like image 168
Momo Avatar answered Sep 18 '22 03:09

Momo