Drag & Drop 를 이용해서 리스트 요소 순서 바꾸기
Last updated
Was this helpful?
Last updated
Was this helpful?
todo list
를 구현했는데, 뭔가 너무 아쉬웠다. 평소에 구현해보고 싶었던 기술중에 Drag & Drop
이 있었는데 todo list
에 적용하기 너무 좋아보여서 시도했다.
DnD 의 인터페이스로는 크게 4가지가 존재한다.
DateEvet
와 DataTranfer
만 알아보자.
이벤트
이벤트 핸들러
설명
dragstart (en-US)
요소나 텍스트 블록을 드래그 할 때 발생한다.
dragend (en-US)
dragenter (en-US)
dragover (en-US)
요소나 텍스트 블록을 적합한 드롭 대상 위로 지나갈 때 발생한다. (매 수백 밀리초마다 발생한다.)
dragleave (en-US)
드래그하는 요소나 텍스트 블록이 적합한 드롭 대상에서 벗어났을 때 발생한다.
drop (en-US)
dragexit
요소가 더 이상 드래그의 직접적인 대상이 아닐 때 발생한다.
Drag 관련 이벤트. 여기서 중요한건 이벤트의 발동 주체가 2가지로 나뉜다는것임.
마우스로 클릭하고 끌고 다니는 요소
drag
dragStart
dragEnd
dragEnter
dragOver (필수로 구현)
dragLeave
drop (필수로 구현)
여기서 주목할 건 Drag
요소를 다른 요소 어딘가에 놓으면 그에 대한 이벤트는 drop
이 발생하고 이 drop
을 핸들링 하는 곳이 Drag
된 요소가 아니라 그 요소와 겹치는 아이템이라는 것.
여기서 의문이 생긴다. Drag
된 요소가 아니라 그 요소가 떨어진 곳에서 Drop
이벤트 핸들러를 실행한다면, Drag
된 요소의 정보는 어떻게 넘겨주는거지? 그 의문은 DataFransfer
에서 해결된다.
get
,set
이외에도 여러 메서드, 프로퍼티가 있다. 필요하면 위의 링크로 가서 보자.
실제로 드래그를 이용해서 리스트 요소의 순서를 바꾸는걸 생각해보자.
요소를 마우스로 잡는다.
마우스로 잡은 요소에서 dragStart
이벤트를 핸들링한다.
끌고 다닌다.
원하는 곳에 내려놓는다.
내려놓은 곳의 요소에서 drop
이벤트가 발동된다.
우리는 1번에서 요소에 대한 정보를 어딘가에 저장해야하고, 그 정보를 3번에서 이용해야한다. 이걸 해주는게 DataTransfer
다. 사용법은 매우 간단하다. setData
를 통해 데이터를 저장하고, getData
를 이용해서 저장된 정보를 불러온다.
실제 사용은 아래처럼 하면된다.
localStorage
처럼 get
, set
으로 사용하면 된다.
아래의 코드는 미래 재사용을 위해
useDragAndDrop
이라는 커스텀훅으로 만들었다.
지금까지 내가 만든 웹요소들은 드래그가 모두 불가능했었다. 왜? 바로
draggable
속성을 넣지 않았기 때문이다. 즉draggable
속성을 넣으면 요소들은 드래깅이 가능해진다.
draggable
속성을 넣음으로써 API 를 사용할 수 있게 된다.
드래그의 시작을 알려준다. 인터페이스 부분에서 설명했다시피 이 부분에서 옮기는 요소에 대한 정보를 저장해야한다.
코드를 분석해보자면
setIsDragging
현재 todo
가 드래그 하는 중이라는걸 알려주는 state
다.
이 값을 통해 todo
는 자신이 드래깅중인지 또는 아닌지를 알 수 있다.
css
핸들링에 사용할 수 있다.
e.dataTransfer.effectedAllowed = move
e.dataTransfer.setData('text/plain', id);
드래그 하는 요소의 정보를 담는다.
Dropzone
tkdghk
e.preventDefault();
기본으로 발동하는 다른 이벤트들을 막는다. (Touch, pointer events..)
setIsDragOver(true);
현재 요소가 드래그 요소의 아래 깔려있음을 말해준다.
Dropzone
const movingTarget = e.dataTransfer.getData('text/plain');
이전에 저장한 데이터를 가져온다.
callback()
todo
요소의 위치를 바꾸는 함수다.
사용자가 요소나 텍스트 블록을 드래그하기 시작했을 때 발생한다. (를 보시오.)
드래그를 끝냈을 때 발생한다. (마우스 버튼을 떼거나 ESC 키를 누를 때) (를 보시오)
드래그한 요소나 텍스트 블록을 적합한 드롭 대상위에 올라갔을 때 발생한다. (를 보시오.)
요소나 텍스트 블록을 적합한 드롭 대상에 드롭했을 때 발생한다. (를 보시오.)
드래그를 해보면 디폴트로 마우스 아래에 +
버튼이 생긴다. 이 버튼을 막아준다. .