In my code below, sometimes when I drag a list item to a new position in the list then release, the clone of the element that is made by the drag, glides back to it’s original position before going to where I dragged to. There is a GIF here that shows the issue.
Any ideas on how to fix this?
var ul = document.querySelector("ul");
function getNextElement(y) {
var next = [...document.querySelectorAll("li")].map(element => {
var rect = element.getBoundingClientRect();
return {
element: element,
top: rect.top
}
}).reduce((a, b) => Math.abs(b.top - y) < Math.abs(a.top - y) ? b : a).element;
next == null ? next = ul.firstElementChild : next;
return next;
}
document.querySelectorAll("li").forEach(draggable => {
draggable.draggable = true;
draggable.ondragstart = event => ul.appendChild(document.createElement("li"));
draggable.ondrag = event => draggable.classList.add("dragging");
draggable.ondragend = event => {
draggable.classList.remove("dragging")
ul.removeChild(ul.lastElementChild)
};
draggable.ondragover = event => {
event.preventDefault();
var next = getNextElement(event.clientY);
var dragging = document.querySelector('.dragging');
if (dragging !== null) {
if (next === null) {
try {
ul.appendChild(dragging);
} catch (error) {
console.log(dragging);
}
} else {
try {
ul.insertBefore(dragging, next);
} catch (error) {
console.log(dragging)
}
}
}
};
});
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400&display=swap');
#container {
position: absolute;
top: 10%;
left: 50%;
transform: translate(-50%, 0%);
width: 200px;
}
ul {
list-style: none;
margin: 0;
font-size: 30px;
font-family: "Inter";
padding-left: 0;
line-height: 40px;
font-size: 16px;
}
li {
width: 200px;
padding-left: 15px;
user-select: none;
overflow: hidden;
cursor: default;
}
li:hover {
background-color: #f6f6f6;
border-radius: 9px;
}
.dragging {
color: transparent;
border: 2px dashed #ddd;
height: 36px;
border-radius: 9px;
background-color: white !important;
}
<div id="container">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>