HTML5 드래그 앤 드롭(DnD)이란?
드래그 앤 드롭(Drag and Drop, DnD)은 마우스 클릭만으로 화면의 요소를 손쉽게 복사하거나, 순서를 변경하고, 삭제할 수 있게 해주는 강력한 사용자 인터페이스(UI) 개념입니다. 사용자는 특정 요소 위에서 마우스 버튼을 누른 채로 원하는 위치까지 끌어다가(drag), 버튼을 놓아(drop) 해당 위치에 요소를 배치할 수 있습니다.
파일 업로드, 할 일 목록 정렬, 이미지 갤러리 재배치 등 다양한 웹 서비스에서 활용되는 이 기능은 HTML5부터 표준 API로 제공되어 별도의 외부 라이브러리 없이도 JavaScript만으로 간편하게 구현할 수 있습니다.
드래그 앤 드롭 구현의 핵심 요소
HTML5에서 드래그 앤 드롭을 구현하려면 다음 세 가지 요소를 이해해야 합니다.
1. draggable 속성: 드래그할 대상 요소에 draggable="true" 속성을 지정해야 해당 요소를 끌 수 있습니다.
2. dragstart 이벤트: 드래그가 시작되는 시점에 발생하는 이벤트로, 이때 전송할 데이터를 설정합니다.
3. dataTransfer 객체: 드래그 중인 데이터를 담고 운반하는 역할을 하는 객체입니다. 주요 메서드는 다음과 같습니다.
effectAllowed: 허용할 드래그 작업의 종류(move, copy 등)를 지정합니다.setData(): 드래그할 데이터를 지정한 형식(예: "Text")으로 저장합니다.setDragImage(): 드래그 중에 표시될 이미지와 좌표 오프셋을 설정합니다.
HTML5 드래그 앤 드롭 예제 코드
다음은 보라색 상자를 마우스로 끌어다 놓을 수 있는 간단한 데모입니다. dragStart 함수에서 dataTransfer 객체를 활용해 드래그 데이터를 설정하는 과정을 확인할 수 있습니다.
<!DOCTYPE HTML>
<html>
<head>
<style>
#boxA, #boxB {float:left;padding:10px;margin:10px; -moz-user-select:none;}
#boxA { background-color: #6633FF; width:75px; height:75px; }
#boxB { background-color: #FF6699; width:150px; height:150px; }
</style>
<script>
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 HTML5 demo</h2>
<div>Try to drag the purple 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이벤트가 발생하고,dragStart(ev)함수가 호출됩니다. effectAllowed를 'move'로 지정해 이동 작업만 허용하도록 설정합니다.setData("Text", ...)를 통해 드래그 대상 요소의 id 값을 데이터로 저장합니다.setDragImage()는 드래그 중 화면에 표시될 미리보기 이미지를 원본 요소 그대로, 오프셋 (0, 0)으로 지정합니다.
실제로 요소를 특정 영역에 '떨어뜨리는(drop)' 동작까지 완성하려면 드롭 대상에 ondragover 이벤트에서 기본 동작을 차단하고(ev.preventDefault()), ondrop 이벤트에서 getData()로 전달된 데이터를 처리하는 코드를 추가로 작성해야 합니다.