- Live Demo : https://mini-drag-and-drop.vercel.app
- React(CRA) + Hooks
- Styled-Components + Babel Plugin Macros
- React Icons
-
드래그할 수 있는 요소로 변경 —
draggable={true}
-
드래그 시작 — onDragStart 이벤트 트리거
- 드래그하고 있는 요소의 인덱스 정보 저장 —
state.draggedFrom
- 드래그 상태 true로 변경 —
state.isDragging
- 이벤트 트리거 시점의 엘리먼트 리스트 저장 —
state.originalOrder
- 드래그하고 있는 요소의 인덱스 정보 저장 —
-
마우스 커서가 드롭 가능한 영역에 있을 때 — onDragOver 이벤트 트리거
-
drop 이벤트를 사용할 수 있도록 dragOver 기본 이벤트 방지 —
e.preventDefault()
-
마우스 포인터 위치에 있는 요소의 인덱스 저장 —
state.draggedTo
-
엘리먼트 순서 변경 —
state.updatedOrder
드래그중인 아이템을 마우스 포인터 위치(draggedTo 인덱스)로 이동. 기존 마우스 포인터 위치에 있던 요소는 바로 뒤로 밀림.
-
-
드롭 가능한 영역에서 드롭했을 때 — onDrop 이벤트 트리거
- 순서를 변경한 엘리먼트 리스트 렌더
- 드래그앤드롭 관련 상태 초기화
HTML 드래그앤드롭 Web API를 이용해 리스트 엘리먼트의 순서를 마우스 드래그앤드롭으로 바꿀 수 있다. 엘리먼트의 draggable
속성을 true
로 주면 해당 요소는 드래그 가능한 객체가 된다. 이미지, 링크, 선택한 텍스트(텍스트 블록)는 기본적으로 드래그가 가능하도록 설정되어있다. 드래그 가능 상태가 되면 onDragStart
같은 드래그 관련 이벤트를 사용할 수 있다. onDragStart
는 드래그가 시작되면 트리거되는 이벤트다.
// 리스트 요소
<div draggable="true" onDragStart={startDragging}>
Drag Me 🍰
</div>
엘리먼트에 onDrop
과 onDragOver
이벤트를 걸면 드롭 가능한 영역(유효한 드롭 대상)이 된다. 이 두 이벤트를 활용해 드래그앤드롭 기능을 구현할 수 있다. onDragOver
는 마우스 포인트에 있는 요소가 유효한 드롭 대상일 때 트리거 되며, onDrop
은 드롭 가능한 영역에서 드롭했을 때 트리거되는 이벤트다.
<section onDrop={updateDragAndDropState} onDragOver={receiveDraggedElements}>
Drop here 🤲🏻
</section>
드래그한 (요소)데이터와 상호 작용하기 위해 setData()
와 getData()
같은 이벤트 메서드를 사용할 수도 있다. 현재 드래그 하고 있는 요소 정보(id 등)를 setData()
를 통해 저장하고, 드롭했을 때 getData()
를 통해 요소 정보를 불러온 후 재정렬 하는 방식으로 활용할 수 있다.
event.dataTransfer.setData(key, value) // 여러 key를 이용해 다수의 데이터를 저장할 수 있다
event.dataTransfer.getData(key)