Subscribe

Vanilla JavaScript Drag n Drop Position

✍️

Lets add a position check to our Drag n Drop editor

19 May, 2020 · 2 min read

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 will look at how we can drop it at a specific position. 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);

With this:

const dropElementY = event.y;

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

if (compTables.length >= 1) {
  for (i = 0; i < compTables.length; i++) {
    const compTablesY1 =
      compTables[i].getBoundingClientRect().y +
      compTables[i].getBoundingClientRect().height / 2;
    const 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 <= compTablesY2) {
      compTables[i].parentNode.insertBefore(clone, compTables[i].nextSibling);
      break;
    }
    dropzone.appendChild(clone);
  }
} else {
  // No tables yet
  dropzone.appendChild(clone);
}

Let’s look at what we are going here.

const dropElementY = event.y;

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

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

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

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

const compTablesY1 =
  compTables[i].getBoundingClientRect().y +
  compTables[i].getBoundingClientRect().height / 2;
const compTablesY2 =
  compTables[i].getBoundingClientRect().y +
  compTables[i].getBoundingClientRect().height;

Then we loop through each element we added, 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);

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 add it after anyway.

Check it out on this 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

Spread the knowledge with fellow developers on Twitter
Tweet this tip
Powered by Webmentions - Learn more

Read next 📖

Removing all vowels with JavaScript

3 Dec, 2022 · 2 min read

Removing all vowels with JavaScript

10 games to learn JavaScript

2 Dec, 2022 · 3 min read

10 games to learn JavaScript

Join 2099 devs and subscribe to my newsletter