'how to check X and Y on draggable element to find closest element
i have followed this video to make drag and drop elements. i already made them work in the X direction, but now i also need to check for the Y direction to find the closets element. so its posable to move the element in any row unlike now as it only checks for the first row.
<html>
<head>
<title>Testing</title>
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>
<body>
<div class="h-64 grid grid-cols-3 gap-4 bg-gray-400 draggable-container">
<div class="bg-red-500 w-full h-32 draggable" draggable="true">1</div>
<div class="bg-red-500 w-full h-32 draggable" draggable="true">2</div>
<div class="bg-red-500 w-full h-32 draggable" draggable="true">3</div>
<div class="bg-red-500 w-full h-32 draggable" draggable="true">4</div>
<div class="bg-red-500 w-full h-32 draggable" draggable="true">5</div>
</div>
<script src="{{ asset('js/products.js') }}"></script>
</body>
</html>
const _doc = document;
const draggables = _doc.querySelectorAll('.draggable'),
constainers = _doc.querySelectorAll('.draggable-container');
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging');
draggable.style.opacity = 0.5;
});
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging');
draggable.style.opacity = 1;
})
})
constainers.forEach(container => {
container.addEventListener('dragover', (event) => {
event.preventDefault()
const draggable = _doc.querySelector('.dragging');
const afterElement = getDragAfterElement(container, event.clientX, event.clientY);
if (afterElement == null) {
container.appendChild(draggable);
} else {
container.insertBefore(draggable, afterElement);
}
})
})
function getDragAfterElement(container, x, y) {
const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offsetX = x - box.left - box.width / 2,
offsetY = y - box.top - box.height / 2;
if (offsetX < 0 && offsetX > closest.offsetX) {
return { offset: offsetX, element: child};
} else {
return closest;
}
}, { offsetX: Number.NEGATIVE_INFINITY }).element;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
