아래 화면처럼 브라우저의 외부 파일 탐색기에서 파일을 드래그 앤 드랍하여 <input type=file>
에 파일을 입력받는 방법입니다. 제이쿼리를 사용하면 좋긴한데 여기서는 제이쿼리 없이 작성했습니다. 호환성을 위해 ES5 이하 스펙으로 작성하였습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ko"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>JS – File Drag and Drop</title> | |
</head> | |
<style> | |
.drop-zone { | |
width: 500px; | |
height: 500px; | |
background-color: azure | |
} | |
.drop-zone-dragenter, .drop-zone-dragover { | |
border: 10px solid blue; | |
} | |
</style> | |
<body> | |
<form> | |
<input type="file" id="file" multiple> | |
<div class="drop-zone"> | |
또는 파일을 여기로 드래그하세요. | |
</div> | |
</form> | |
<script> | |
(function() { | |
var $file = document.getElementById("file") | |
var dropZone = document.querySelector(".drop-zone") | |
var toggleClass = function(className) { | |
console.log("current event: " + className) | |
var list = ["dragenter", "dragleave", "dragover", "drop"] | |
for (var i = 0; i < list.length; i++) { | |
if (className === list[i]) { | |
dropZone.classList.add("drop-zone-" + list[i]) | |
} else { | |
dropZone.classList.remove("drop-zone-" + list[i]) | |
} | |
} | |
} | |
var showFiles = function(files) { | |
dropZone.innerHTML = "" | |
for(var i = 0, len = files.length; i < len; i++) { | |
dropZone.innerHTML += "<p>" + files[i].name + "</p>" | |
} | |
} | |
var selectFile = function(files) { | |
// input file 영역에 드랍된 파일들로 대체 | |
$file.files = files | |
showFiles($file.files) | |
} | |
$file.addEventListener("change", function(e) { | |
showFiles(e.target.files) | |
}) | |
// 드래그한 파일이 최초로 진입했을 때 | |
dropZone.addEventListener("dragenter", function(e) { | |
e.stopPropagation() | |
e.preventDefault() | |
toggleClass("dragenter") | |
}) | |
// 드래그한 파일이 dropZone 영역을 벗어났을 때 | |
dropZone.addEventListener("dragleave", function(e) { | |
e.stopPropagation() | |
e.preventDefault() | |
toggleClass("dragleave") | |
}) | |
// 드래그한 파일이 dropZone 영역에 머물러 있을 때 | |
dropZone.addEventListener("dragover", function(e) { | |
e.stopPropagation() | |
e.preventDefault() | |
toggleClass("dragover") | |
}) | |
// 드래그한 파일이 드랍되었을 때 | |
dropZone.addEventListener("drop", function(e) { | |
e.preventDefault() | |
toggleClass("drop") | |
var files = e.dataTransfer && e.dataTransfer.files | |
console.log(files) | |
if (files != null) { | |
if (files.length < 1) { | |
alert("폴더 업로드 불가") | |
return | |
} | |
selectFile(files) | |
} else { | |
alert("ERROR") | |
} | |
}) | |
})(); | |
</script> | |
</body></html> |
<input type=file>
에서multiple
속성을 추가하면 여러 파일을 입력받을 수 있습니다.drop-zone
이라는 클래스의 첫 번째 요소에 파일을 드래그 앤 드랍하면 이벤트가 발생합니다.- 드래그 앤 드랍 이벤트에서 자주 사용되는 속성은
dragover
,drop
입니다.dragover
는 드래그한 파일들이 영역 안에 들어가 있을 때,drop
은 마우스 버튼을 떼고 드랍되었을 때 발생하는 이벤트입니다. - 브라우저 기본 동작 방지와 버블링 방지 목적으로
e.preventDefault()
,e.stopPropagation()
을 추가합니다. (관련 글) selectFile
함수에서 input file을 대체하는 작업을 수행합니다. 이 예제는 여러 파일이 허용된다는 전제하에 저렇게 작성되었고, 만약 단일 파일만 허용해야 한다면 방어 코드를 작성해 파일 입력이 되지 않도록 하거나 또는 아래와 같이 첫 번째 파일만 대체되도록 하세요.$file.files[0] = files[0]
- 드랍된 파일이 정상적인 파일인 경우 파일들은
e.dataTransfer.files
에 담기게 됩니다.
참고 블로그 바로가기
0개의 댓글