전체 페이지 드래그 앤 드롭이란?
파일 업로드 기능을 가진 웹사이트에서는 특정 영역뿐 아니라 브라우저 화면 전체에 파일을 끌어다 놓아(drag & drop) 업로드할 수 있도록 지원하면 사용자 경험이 크게 향상됩니다. 사용자가 어디에나 파일을 놓을 수 있다는 점에서 직관적이며, 별도의 버튼 클릭 없이 빠르게 파일을 전송할 수 있습니다.
아래 코드는 HTML과 순수 JavaScript만으로 전체 페이지 드래그 앤 드롭을 구현한 예제입니다.
전체 코드 예제
var myDrop = document.getElementById('dropZone');
function displayDropZone() {
myDrop.style.visibility = "visible";
}
function hideDropZone() {
myDrop.style.visibility = "hidden";
}
function allowDrag(ev) {
if (true) {
ev.dataTransfer.dropEffect = 'copy';
ev.preventDefault();
}
}
function handleDrop(ev) {
ev.preventDefault();
hideDropZone();
alert('This is Drop!');
}
window.addEventListener('dragenter', function(ev) {
displayDropZone();
});
myDrop.addEventListener('dragenter', allowDrag);
myDrop.addEventListener('dragover', allowDrag);
myDrop.addEventListener('dragleave', function(e) {
hideDropZone();
});
myDrop.addEventListener('drop', handleDrop);코드 동작 방식 설명
1. 드롭 존 표시 및 숨기기
displayDropZone() 함수는 드롭 존 요소의 visibility를 visible로 변경하여 화면에 표시하고, hideDropZone()은 반대로 hidden으로 설정해 숨깁니다. 사용자가 파일을 끌어오기 시작하면 드롭 존이 나타나고, 작업이 끝나면 자동으로 사라지는 방식입니다.
2. 드래그 허용 처리 (allowDrag)
allowDrag() 함수는 dragenter와 dragover 이벤트에서 호출됩니다. 이 두 이벤트에서 ev.preventDefault()를 호출하지 않으면 브라우저가 기본 동작(파일 열기 등)을 수행해 버리므로 반드시 막아야 합니다. 또한 ev.dataTransfer.dropEffect = 'copy'를 지정하면 마우스 커서가 '복사' 형태로 표시되어 사용자에게 시각적 피드백을 줄 수 있습니다.
3. 파일 드롭 처리 (handleDrop)
handleDrop() 함수는 실제로 파일이 놓였을 때 실행됩니다. 여기서도 preventDefault()로 기본 동작을 차단한 뒤, 드롭 존을 숨기고 필요한 파일 처리 로직을 수행합니다. 예제에서는 간단히 알림창을 띄우지만, 실제 서비스에서는 ev.dataTransfer.files를 통해 파일 객체에 접근하여 업로드를 진행하면 됩니다.
4. 이벤트 리스너 등록
- window의 dragenter: 페이지 어디든 파일이 들어오면 드롭 존을 표시합니다.
- dropZone의 dragenter / dragover: 드롭이 가능하도록 허용합니다.
- dropZone의 dragleave: 파일이 드롭 존을 벗어나면 드롭 존을 숨깁니다.
- dropZone의 drop: 파일이 놓이면 실제 처리 로직을 실행합니다.
구현 시 주의 사항
드래그 앤 드롭을 구현할 때는 dragenter와 dragleave가 자식 요소를 오갈 때마다 연속적으로 발생한다는 점에 유의해야 합니다. 이로 인해 드롭 존이 깜빡이는 현상이 발생할 수 있는데, 카운터 변수를 활용하거나 CSS의 pointer-events: none 속성을 적용하면 이 문제를 해결할 수 있습니다.