다 같이 살펴보면 좋은것은 다음과 같은 함수 입니다👇👇 다음 함수의 역할은 쉽게 설명하면 하나의 Element를 마우스드레그를 하고, 이후에 어떤 Element를 인지 가져오는 함수 입니다.
이벤트가 발생할때 getDragAfterElement(컨테이너Element, 수직 좌표) 함수에 각각의 2개 인자를 넘겨주고 draggableElements은 .draggable클래스에 .dragging라는 클래가 없는 엘리머트를 모두 배열로 가져오는것입니다.
draggableElements을 reduce로 루프를 돌려, 수직 좌표 - top값 - height값 / 2의 연산을 통해서 offset변수에 할당하였고 (예외 처리) 0 이하 와, 음의 무한대 사이에 Element를 리턴하는것 입니다.
결국에는 getDragAfterElement함수는 내가 마우스 드래그하고 마지막 위치해놓은 Element를 리턴하는것 입니다.
function getDragAfterElement(container, y) { //마지막 위치해놓은 Element를 리턴하는 함수
const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect() //해당 엘리먼트에 top값, height값 담겨져 있는 메소드를 호출해 box변수에 할당
const offset = y - box.top - box.height / 2 //수직 좌표 - top값 - height값 / 2의 연산을 통해서 offset변수에 할당
if (offset < 0 && offset > closest.offset) { // (예외 처리) 0 이하 와, 음의 무한대 사이에 조건
return { offset: offset, element: child } // Element를 리턴
} else {
return closest
}
}, { offset: Number.NEGATIVE_INFINITY }).element
};
containers.forEach(container => {
container.addEventListener('dragover', e => {
e.preventDefault()
const afterElement = getDragAfterElement(container, e.clientY); //(결국 드래그하여 마지막 영역의 엘리먼트를 반환합니다.)
const currentDraggable = document.querySelector('.dragging'); //현재 내가 잡은 엘리먼트
container.insertBefore(currentDraggable, afterElement); //마지막까지 드래그한 엘리먼트 앞에 현재 내가 잡은 엘리먼트를 삽입 합니다.
})
});
👉전체 소스코드(JS)
(() => {
const $ = (select) => document.querySelectorAll(select);
const draggables = $('.draggable');
const containers = $('.container');
draggables.forEach(el => {
el.addEventListener('dragstart', () => {
el.classList.add('dragging');
});
el.addEventListener('dragend', () => {
el.classList.remove('dragging')
});
});
function getDragAfterElement(container, y) {
const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect() //해당 엘리먼트에 top값, height값 담겨져 있는 메소드를 호출해 box변수에 할당
const offset = y - box.top - box.height / 2 //수직 좌표 - top값 - height값 / 2의 연산을 통해서 offset변수에 할당
if (offset < 0 && offset > closest.offset) { // (예외 처리) 0 이하 와, 음의 무한대 사이에 조건
return { offset: offset, element: child } // Element를 리턴
} else {
return closest
}
}, { offset: Number.NEGATIVE_INFINITY }).element
};
containers.forEach(container => {
container.addEventListener('dragover', e => {
e.preventDefault()
const afterElement = getDragAfterElement(container, e.clientY); //(결국 드래그하여 마지막 영역의 엘리먼트를 반환합니다.)
const currentDraggable = document.querySelector('.dragging'); //현재 내가 잡은 엘리먼트
container.insertBefore(currentDraggable, afterElement); //마지막까지 드래그한 엘리먼트 앞에 현재 내가 잡은 엘리먼트를 삽입 합니다.
})
});
})();