HTML5 드래그 앤 드롭(DnD)이란?
드래그 앤 드롭(Drag and Drop, DnD)은 마우스 조작만으로 화면의 요소를 손쉽게 복사하거나 순서를 변경하고 삭제할 수 있게 해주는 강력한 사용자 인터페이스(UI) 개념입니다. 사용자는 특정 요소 위에서 마우스 버튼을 누른 채 유지한 상태로 원하는 위치까지 끌어간 뒤, 버튼을 놓으면 그 자리에 요소가 배치됩니다.
기존 HTML4 환경에서 드래그 앤 드롭 기능을 구현하려면 복잡한 자바스크립트(JavaScript) 코드를 직접 작성하거나 jQuery 같은 외부 프레임워크에 의존해야 했습니다.
하지만 HTML5에서는 드래그 앤 드롭(DnD) API가 표준으로 도입되어 브라우저 차원의 네이티브 DnD 기능을 제공하게 되었고, 덕분에 개발자가 훨씬 적은 코드로 이 기능을 구현할 수 있게 되었습니다.
드래그 앤 드롭 구현 방법
HTML5에서 드래그 앤 드롭을 구현하려면 크게 두 단계를 거쳐야 합니다.
1단계: 객체를 드래그 가능하게 만들기
드래그 앤 드롭 구현의 첫 번째 단계는 드래그할 대상 객체를 지정하는 것입니다.
- 드래그하고 싶은 요소에
draggable속성을true로 설정합니다. dragstart이벤트 리스너를 등록하여 드래그 중인 데이터를 저장합니다.dragstart이벤트 리스너에서 허용된 효과(copy, move, link 또는 이들의 조합)를 함께 지정할 수 있습니다.
예제
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#boxA, #boxB {
float:left;padding:10px;margin:10px; -moz-user-select:none;
}
#boxA { background-color: #50B948; width:75px; height:75px; }
#boxB { background-color: #0000FF; width:150px; height:150px; }
</style>
<script type="text/javascript">
function dragStart(ev) {
ev.dataTransfer.effectAllowed='move';
ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));
ev.dataTransfer.setDragImage(ev.target,0,0);
return true;
}
</script>
</head>
<body>
<center>
<h2>Drag and drop in HTML5</h2>
<div>Try to drag the green box around.</div>
<div id="boxA" draggable="true"
ondragstart="return dragStart(ev)">
<p>Drag Me</p>
</div>
<div id="boxB">Dustbin</div>
</center>
</body>
</html>위 예제에서는 초록색 박스(#boxA)에 draggable="true"를 설정하고, ondragstart 이벤트에서 dataTransfer 객체를 통해 이동 효과(move)와 요소의 ID를 전달하도록 했습니다.
2단계: 객체 드롭하기
드롭을 받아들이려면 드롭 대상(drop target)이 최소 세 가지 이벤트를 처리해야 합니다.
- dragenter: 드롭 대상이 해당 드롭을 수락할지 여부를 결정합니다. 드롭을 수락하려면 이 이벤트를 반드시 취소(cancel)해야 합니다.
- dragover: 사용자에게 어떤 피드백을 보여줄지 결정합니다. 드롭을 허용하려면 이 이벤트 역시 취소해야 합니다.
- drop: 실제로 요소가 놓였을 때 전달된 데이터를 처리하고 원하는 동작을 수행합니다.

다음 예제는 초록색 박스를 파란색 박스(휴지통) 안으로 옮기는 방법을 보여줍니다.
예제
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#boxA, #boxB {
float:left;padding:10px;margin:10px;-moz-user-select:none;
}
#boxA { background-color: #50B948; width:75px; height:75px; }
#boxB { background-color: #0000FF; width:150px; height:150px; }
</style>
<script type="text/javascript">
function dragStart(ev) {
ev.dataTransfer.effectAllowed='move';
ev.dataTransfer.setData("Text", ev.target.getAttribute('id'));
ev.dataTransfer.setDragImage(ev.target,0,0);
return true;
}
function dragEnter(ev) {
event.preventDefault();
return true;
}
function dragOver(ev) {
return false;
}
function dragDrop(ev) {
var src = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(src));
ev.stopPropagation();
return false;
}
</script>
</head>
<body>
<center>
<h2>Drag and drop in HTML5</h2>
<div>Try to move the green box into the blue box.</div>
<div id="boxA" draggable="true"
ondragstart="return dragStart(ev)">
<p>Drag Me</p>
</div>
<div id="boxB" ondragenter="return dragEnter(ev)"
ondrop="return dragDrop(ev)"
ondragover="return dragOver(ev)">Dustbin
</div>
</center>
</body>
</html>이 예제에서 dragDrop 함수는 dataTransfer.getData()로 드래그 시작 시 저장해 둔 요소 ID를 읽어온 뒤, 해당 요소를 드롭 대상의 자식 노드로 추가합니다. 이렇게 하면 초록색 박스가 파란색 박스 안으로 실제로 이동하는 것처럼 동작합니다.
마무리
HTML5의 네이티브 DnD API를 활용하면 외부 라이브러리 없이도 직관적인 드래그 앤 드롭 인터페이스를 만들 수 있습니다. draggable 속성으로 드래그 대상을 지정하고, dragstart, dragenter, dragover, drop 이벤트를 적절히 조합하면 파일 업로드, 목록 재정렬, 휴지통 기능 등 다양한 사용자 경험(UX)을 손쉽게 구현할 수 있습니다.