Meine ziehbaren Elemente werden horizontal in einem angehängt hoher Container (groupPanel) und fließt in die nächste Zeile, sobald 100 % der Breite aufgebraucht sind.
Der folgende Code funktioniert nur, bis das erste ziehbare Element in die nächste Zeile fließt. Ich habe versucht, mit CSS (Raster und Flexbox) zu arbeiten, aber nichts hat die frühere Funktionalität erreicht.
Ich habe den Code umgeschrieben, um zusätzliche DIV-Container in Zeilen als Platzierungsbereiche für die Elemente zu platzieren; Das funktioniert ganz gut, ist aber nicht wirklich das, was ich will, da ich einige Zeit damit verbringen möchte, eine Logik für die beste dynamische Raumnutzung vor dem Falten/Fließen zu entwickeln.
Das habe ich habe versucht, e.clientY auch an die Funktion getDragAfterElement zu übergeben und den kürzesten kombinierten Versatz zu den nächstgelegenen vertikalen und horizontalen ziehbaren Elementen zu berechnen, aber die Positionen der resultierenden afterElements ergaben überhaupt keinen Sinn und flackerten bei Mausbewegung.
Ist Gibt es etwas, das getan werden kann, um den Codetyp unten zu belassen, aber funktioniert er auch, nachdem Elemente in weitere Zeilen fließen?
Oder sollte ich den Plan aufgeben und einen völlig anderen Ansatz verwenden mit voller x-y-Kontrolle?
Code: Select all
// Drag n Drop
function dragDropp() {
const draggables = document.querySelectorAll('.draggable')
const dragContainers = document.querySelectorAll('.groupPanel')
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging');
})
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
saveOrder()
})
})
dragContainers.forEach(groupPanel => {
groupPanel.addEventListener('dragover', e => {
e.preventDefault()
const afterElement = getDragAfterElement(groupPanel, e.clientX)
let draggable = document.querySelector('.dragging')
if (afterElement == null) {
groupPanel.appendChild(draggable)
} else {
groupPanel.insertBefore(draggable, afterElement)
}
})
})
}
function getDragAfterElement(container, x) {
const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')];
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = x - box.left - box.width / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
}, { offset: Number.NEGATIVE_INFINITY }).element
}
Bearbeiten: Ich komme einem näher Lösung, aber bisher fühlt es sich nur zu etwa 80 % richtig an. Ich berechne die Mitte (x und y) jedes ziehbaren Elements und mittele die Abstände x zu x und y zu y zwischen Cursor und Element.
Natürlich ist die Mittelung nicht genau, da keine Triangulation beteiligt ist, aber es ist eine Anfang.
Ich hätte wirklich gedacht, dass dies eine häufige Aufgabe ist und die Antwort einfach auftauchen würde
