
현재 칸반보드를 구현 중이며, 드래그 앤 드롭 기능을 구현하기 위해 HTML5 Drag and Drop API를 공부하고 정리하였습니다. HTML5 Drag and Drop API는 기본적인 개념을 익히기에 적합하지만, 모바일 환경에서 기본적으로 지원되지 않는 한계가 있습니다. 따라서 실제 프로젝트에서는 React DnD와 같은 라이브러리를 활용하는 것이 더 적합하다고 합니다.
이 글에서는 HTML5 Drag and Drop API의 기초 개념과 동작을 학습한 내용을 정리하였습니다!
드래그 앤드 드롭(Drag and Drop) 이란?
드래그 앤드 드롭(Drag and Drop)은 사용자가 화면 상의 요소를 선택하여 끌어다 놓는 방식으로 인터페이스와 상호작용할 수 있는 기능입니다. 이는 웹 애플리케이션에서 직관적인 사용자 경험(UX)을 제공하는 데 많이 사용됩니다.
HTML5 Drag and Drop API
HTML5에서 제공하는 Drag and Drop API는 기본적으로 HTML 요소에 드래그 앤드 드롭 동작을 구현할 수 있게 해줍니다.
HTML drag-and-drop 은 DOM 이벤트 모델과 마우스 이벤트에서 상속된 드래그 이벤트를 사용합니다.
드래그 작업은 사용자가 드래그 가능한 요소를 선택할 때 시작되고 요소를 놓을 수 있는 요소로 드래그 할 때 계속되며 사용자가 드래그한 요소를 놓을 때 끝납니다.
드래그 작업 중 여러 이벤트 유형이 발생하며 이벤트 유형은 다음과 같습니다.
이벤트 | 이벤트 발생 조건 |
drag | 드래그된 아이템이 드래그 되는 동안 발생 |
dragend | 드래그 작업이 끝날 때 발생 (마우스 버튼을 놓거나 ESC 키를 누를 때 ) |
dragenter | 드래그된 아이템이 유효한 드롭 대상에 들어갈 때 발생 |
dragleave | 드래그된 아이템이 유효한 드롭 대상을 떠날 때 발생 |
dragover | 드래그된 아이템이 유효한 드롭 대상 위에서 드래그 될 때 발생 |
dragstart | 사용자가 아이템 드래그를 시작할 때 발생 |
drop | 아이템이 유효한 드롭 대상에 놓일 때 발생 |
드래그 가능한 속성 만들기
HTML 요소 중 텍스트, 이미지, 링크는 기본적으로 드래그가 가능하지만, 다른 요소는 draggable 속성을 명시적으로 설정해야 드래그 동작을 지원합니다.
1. 드래그 할 요소에 draggable 속성을 true로 설정
<div id="draggable" draggable="true">Drag me</div>
2. dragstart 이벤트 리스너 추가 및 데이터 설정
- format: 데이터 형식을 지정합니다. 일반적으로 "text/plain" 사용
- data: 드래그 동작 중에 전달할 데이터
const draggable = document.getElementById('draggable');
draggable.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', 'This is a draggable element');
console.log('Drag started');
});
드롭 영역 설정하기
드롭 영역(drop target)은 드래그 된 요소를 놓을 수 있는 영역입니다. 드롭 영역을 설정하려면 dragover와 drop 이벤트를 처리해야 합니다. 특히, 드롭 영역에서는 기본 동작 방지를 해야만 드롭 동작이 정상적으로 작동합니다.
1. 드롭 영역 설정
드롭 영역으로 설정할 요소에 dragover와 drop 이벤트 리스너를 추가합니다
<div id="dropzone" style="width: 200px; height: 200px; border: 2px dashed lightgray;">
Drop here
</div>
2. dragover이벤트 리스너
dragover 이벤트는 드래그된 요소가 드롭 영역 위로 이동할 때 발생합니다. 기본 동작을 방지(e.preventDefault())하지 않으면 drop 이벤트가 실행되지 않습니다.
const dropzone = document.getElementById('dropzone');
dropzone.addEventListener('dragover', (e) => {
e.preventDefault(); // 기본 동작 방지 (드롭 가능하도록 설정)
console.log('Dragging over dropzone');
});
3. drop 이벤트 리스너
drop 이벤트는 드래그된 요소가 드롭 영역에 놓일 때 발생합니다. 이 이벤트를 사용하여 드래그 데이터를 가져오고, 필요한 동작을 수행할 수 있습니다.
dropzone.addEventListener('drop', (e) => {
e.preventDefault(); // 기본 동작 방지
const data = e.dataTransfer.getData('text/plain'); // 드래그된 데이터 가져오기
console.log('Dropped data:', data);
});
예제 코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drag and Drop Example</title>
<style>
#draggable {
width: 100px;
height: 100px;
background-color: lightblue;
cursor: grab;
}
#dropzone {
width: 200px;
height: 200px;
border: 2px dashed lightgray;
margin-top: 20px;
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<!-- 드래그 가능한 요소 -->
<div id="draggable" draggable="true">Drag me</div>
<!-- 드롭 영역 -->
<div id="dropzone">Drop here</div>
<script>
// 드래그 가능한 요소 설정
const draggable = document.getElementById('draggable');
draggable.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', 'This is a draggable element');
console.log('Drag started');
});
// 드롭 영역 설정
const dropzone = document.getElementById('dropzone');
dropzone.addEventListener('dragover', (e) => {
e.preventDefault(); // 기본 동작 방지
console.log('Dragging over dropzone');
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault(); // 기본 동작 방지
const data = e.dataTransfer.getData('text/plain');
console.log('Dropped data:', data);
});
</script>
</body>
</html>

참고 링크
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API