See: https://simplexshotz.github.io/Sorting-Dropping/
When you drag a sortable past another (so that they swap positions), the offset positions (element.offsetTop, element.offsetLeft) don't update.
How the above example should work is as follows: if you drop a sortable over another, an alert will be displayed telling you which sortable you dropped it over. If the cursor is not over another sortable when you drop it, no alert should be displayed.
The only issue with it is that when you drop it, whether or not is is over a sortable is based off of the sortable's original position. If you drag a sortable past another (so that they swap positions) and drop it where the sortable was before they swapped positions, the alert still appears. This leads me to believe that the offset is using the previous position.
var order = [];
function setup() {
// Add the sortables:
for (var i = 0; i < 5; i++) {
document.getElementById("container").innerHTML += "<div class='sortable' id='sortable-" + i + "'>Sortable " + i + "</div>";
order.push(i);
}
// Make them actually sortable:
$("#container").sortable({
stop: function(e, ui) {
// Detect drop over another sortable:
var s = document.getElementById("container").childNodes;
var c = Number(ui.item[0].id.split("-")[1]); // this is the index of the sortable that was being moved
for (var i = 0; i < s.length; i++) {
if (order[i] !== c) { // Make sure it's not checking if the cursor is over itself
// Basic pixel -> rectangle collisions:
if (e.clientX >= s[i].offsetLeft && e.clientY >= s[i].offsetTop && e.clientX <= s[i].offsetLeft + s[i].offsetWidth && e.clientY <= s[i].offsetTop + s[i].offsetHeight) {
console.log("Sortable dropped over sortable " + order[i]);
break;
}
}
}
// Re-order them:
for (var i = 0; i < s.length; i++) {
order[i] = Number(s[i].id.split("-")[1]);
}
}
});
}
setup();
* {
font-family: Helvetica;
}
body {
background-color: rgb(255, 255, 255);
padding: 0px;
margin: 0px;
}
#container {
border: 1px solid rgb(200, 200, 200);
border-radius: 10px;
padding: 20px;
margin: 50px 25% 0px 25%;
}
.sortable {
border-radius: 10px;
background-color: rgb(50, 50, 50);
color: rgb(255, 255, 255);
padding: 10px;
width: calc(100% - 20px);
margin-bottom: 10px;
}
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<!-- JQuery -->
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div id="content">
<div id="container"></div>
</div>
</body>
</html>
Sorry if that's a bit complicated, I'm not sure how else to explain it.
Any help is appreciated. Thanks in advance.
This isn't a problem with the offset. It's not working as you expect because order[i] !== c
isn't ruling out that the cursor is over the final position of the element you just moved, it's ruling out that the cursor is over the starting (previous) position of the element you just moved.