📌 핵심 개념
- 드래그 소스: 끌려가는 대상 (ex. 이미지)
- 드롭 타겟: 끌려온 걸 놓는 위치 (ex. 장바구니 박스)
💡 img 태그는 기본적으로 드래그 가능
⚙️ 사용 흐름
- 드래그 가능한 요소에
dragstart
이벤트를 설정한다.
- 드롭 대상에
dragover
이벤트에서 e.preventDefault()
로 기본 동작을 막는다.
- 사용자가 마우스를 놓으면
drop
이벤트가 실행된다.
- 필요하다면 드래그가 끝났을 때
dragend
에서 정리 작업을 한다.
🧩 주요 이벤트
이벤트명 | 대상 | 설명 |
---|
dragstart | 소스 | 드래그 시작 시 실행됨. dataTransfer 에 데이터 저장 가능 |
drag | 소스 | 드래그 중 계속 발생함 (마우스 움직일 때마다) |
dragenter | 타겟 | 드래그 요소가 드롭 가능한 영역에 들어왔을 때 |
dragleave | 타겟 | 드롭 영역에서 벗어날 때 |
dragover | 타겟 | 드롭 영역 위에서 움직일 때. 반드시 e.preventDefault() 해야 drop 가능 |
drop | 타겟 | 마우스를 놓았을 때 실행됨. 드래그된 데이터 접근 가능 |
dragend | 소스 | 드래그 작업이 종료될 때. drop 성공/실패와 무관하게 실행됨 |
🧪 실행 순서
dragstart
– (드래그 시작)
drag
– (마우스 움직이는 동안 반복적으로 발생)
dragenter
– (타겟 영역에 진입)
dragover
– (타겟 위에서 움직이는 동안 계속 발생)
drop
– (마우스 버튼을 놓는 순간)
dragend
– (드래그 행위가 끝나면 항상 발생)
🧾 예제 코드
<img src="apple.jpg" draggable="true" id="item" />
<div id="cart">장바구니</div>
const item = document.getElementById("item");
const cart = document.getElementById("cart");
item.addEventListener("dragstart", (e) => {
e.dataTransfer.setData("text/plain", "apple");
});
cart.addEventListener("dragover", (e) => {
e.preventDefault();
});
cart.addEventListener("drop", (e) => {
e.preventDefault();
const data = e.dataTransfer.getData("text/plain");
cart.innerText = `${data}가 장바구니에 담겼습니다!`;
});
📎 드롭과 dragend 차이점
이벤트 | 발생 위치 | 실행 기준 |
---|
drop | 타겟 영역 | 마우스 버튼을 놓는 순간 |
dragend | 드래그한 요소(소스) | 드래그 작업이 끝날 때 항상 실행됨 (성공/실패 관계없음) |
✅ 유의사항
dragover
에서 e.preventDefault()
를 반드시 해줘야 drop
이 작동함!!!!
dataTransfer.setData()
로 데이터를 저장하고, getData()
로 꺼내서 사용
img
는 기본적으로 draggable="true"
이므로 따로 설정 필요 없다