DEV Community

Cover image for Vanilla JavaScript Drag n Drop Position
Chris Bongers
Chris Bongers

Posted on • Originally published at daily-dev-tips.com

Vanilla JavaScript Drag n Drop Position

We've been working on this Drag 'n Drop editor for a couple of days now, and we set up the basic Drag 'n Drop.
Then we made sure we could remove elements.
Now we are going to look at how we can drop it at a specific position.
Let's say we drop it at the top half of the other element, which it should insert above. And if we drop on the bottom half, it must appear under it.

HTML, CSS Changes

The good part is we don't need any CSS or HTML changes for this!

JavaScript position detection

We are going to work inside the onDrop function.

Let's replace the following code

dropzone.appendChild(clone);
Enter fullscreen mode Exit fullscreen mode

With this:

const dropElementY = event.y;

// Get all main tables in the dropzone and get those positions based off the y position
var compTables = dropzone.querySelectorAll('.actual-comp');

if (compTables.length >= 1) {
  for (i = 0; i < compTables.length; i++) {
    var compTablesY1 =
      compTables[i].getBoundingClientRect().y +
      compTables[i].getBoundingClientRect().height / 2;
    var compTablesY2 =
      compTables[i].getBoundingClientRect().y +
      compTables[i].getBoundingClientRect().height;

    // Check if dropElementY is smaller then compTablesY1 (insert above)
    if (dropElementY <= compTablesY1) {
      compTables[i].parentNode.insertBefore(clone, compTables[i]);
      break;
    }
    // Check if dropElementY is smaller then compTablesY2 (insert below)
    if (dropElementY <= emailTableY2) {
      compTables[i].parentNode.insertBefore(clone, compTables[i].nextSibling);
      break;
    }
    dropzone.appendChild(clone);
  }
} else {
  // No tables yet
  dropzone.appendChild(clone);
}
Enter fullscreen mode Exit fullscreen mode

Let's look at what we are going here.

const dropElementY = event.y;
Enter fullscreen mode Exit fullscreen mode

Here we are getting the vertical position of our dropped element.

var compTables = dropzone.querySelectorAll('.actual-comp');

if (compTables.length >= 1) {
  // code
} else {
  // No tables yet
  dropzone.appendChild(clone);
}
Enter fullscreen mode Exit fullscreen mode

Then we get all component tables that we already added.
If there are none it's the first element and we just append it as we did before.

var compTablesY1 =
  compTables[i].getBoundingClientRect().y +
  compTables[i].getBoundingClientRect().height / 2;
var compTablesY2 =
  compTables[i].getBoundingClientRect().y + compTables[i].getBoundingClientRect().height;
Enter fullscreen mode Exit fullscreen mode

Then we loop through each element we added and we are defining a Y1 (top half of the element) and Y2 max height of the element.

// Check if dropElementY is smaller then compTablesY1 (insert above)
if (dropElementY <= compTablesY1) {
    compTables[i].parentNode.insertBefore(clone, compTables[i]);
    break;
}
// Check if dropElementY is smaller then compTablesY2 (insert below)
if (dropElementY <= emailTableY2) {
    compTables[i].parentNode.insertBefore(clone, compTables[i].nextSibling);
    break;
}
dropzone.appendChild(clone);
Enter fullscreen mode Exit fullscreen mode

We then check if our dropped element vertical position is smaller than the Y1 we insert it before.
If it's smaller than the Y2 we add it after and else we just add it after anyway.

Check if out on Codepen.

See the Pen Vanilla JavaScript Drag 'n Drop - Position by Chris Bongers (@rebelchris) on CodePen.

Or download on GitHub.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Top comments (0)