Vanilla JavaScript Drag n Drop Position

— 6 minute read

permalink

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 permalink

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

JavaScript position detection permalink

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
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);
}

Let's look at what we are going here.

const dropElementY = event.y;

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);
}

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;

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);

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! permalink

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