오늘은 라이브러리가 아닌 JS만으로 Drag & Drop을 구현해보자
Drag & Drop을 구현하기 위해서는 해당 document에 draggable
속성을 줘야한다.
<li data-id="${id}" draggable="true"> 드래그 & 드랍 </li>
Drag & Drop에 필요한 이벤트와 메서드가 있다.
다양한 이벤트가 있지만 여기서는 4가지만 사용해본다.
dragstart, dragover, drop 그리고 datatransfer 메서드
가 있다
datatransfer는 Drag & drop을 사용하는데 필요한 메서드 이고 Drag & drop이 되는 대상의 data를 담고 꺼내 쓰는 역할을 한다.
li.addEventListener("dragstart", (e) => {
const $li = e.target.closest("li");
e.dataTransfer.setData("키 값", $li.dataset.id);
});
drag가 시작되었을 때 발생하는 이벤트이며, 어떤 document를 drag했는지 dataTransfer에 setData(키, 값)
으로 넣어놓고 나중에 drop할 때 꺼내 쓸 수 있다.
li.addEventListener("dragover", (e) => {
e.preventDefault();
e.dataTransfer.dropEffect = "move";
});
dragover는 drop 대상에서 발생하는 이벤트다
li.addEventListener("drop", (e) => {
// drop 지역을 정의할 때, preventDefault를 해줘야한다.
// 그렇지 않으면 다른 이벤트들도 막 일어날 수 있다.
e.preventDefault();
const droppedId = e.dataTransfer.getData("키 값");
console.log(droppedId) // 드래그한 요소의 데이터를 가져올 수 있다. ex) document의 정보
//현재 list 영역에서 D&D가 발생하지 않는 경우 상위 컴포넌트에게 알리고 커스텀 함수를 발생시킨다.
const { todos } = this.state;
if (!todos.find((todo) => todo._id === droppedTodoId)) {
onDrop(droppedTodoId);
}
});
drop은 마우스에서 drag가 끝났을 때, 발생하는 이벤트로 드래그한 요소를 통해 하나의 list 영역에서 다른 list 영역으로 보낼 때, 드래그한 요소의 정보를 다른 list 영역으로 옮겨 화면에 그려주면 원하는 drag & drop이 발생한 것을 볼 수 있다.
드래그 이벤트 MDN
프로그래머스