Skip to content

Instantly share code, notes, and snippets.

@luciopaiva
Last active September 7, 2018 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luciopaiva/1e085b1b7d25999f55725c1c30beb585 to your computer and use it in GitHub Desktop.
Save luciopaiva/1e085b1b7d25999f55725c1c30beb585 to your computer and use it in GitHub Desktop.
File drop zone
class FileDropZone {
/**
* @param {HTMLElement|String} dropZoneElement
*/
constructor (dropZoneElement) {
dropZoneElement = typeof dropZoneElement === "string" ? document.getElementById(dropZoneElement) : dropZoneElement;
dropZoneElement.addEventListener("drop", this.onDrop.bind(this));
dropZoneElement.addEventListener("dragover", event => event.preventDefault());
this.listeners = new Set();
}
/**
* @param {Function} callback
*/
onFile(callback) {
this.listeners.add(callback);
}
/**
* @param {DragEvent} event
*/
async onDrop(event) {
event.preventDefault();
if (event.dataTransfer.files && event.dataTransfer.files.length > 0) {
const file = event.dataTransfer.files[0]; // get the first, ignore any others
const contents = await FileDropZone.readFile(file);
this.listeners.forEach(listener => listener(contents));
}
}
/**
* @param {File} file
*/
static async readFile(file) {
const reader = new FileReader();
return await new Promise(resolve => {
reader.addEventListener("load", event => resolve(event.target.result));
reader.readAsText(file);
});
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Drag-and-drop example</title>
<style>
body {
padding: 0;
margin: 0;
overflow: hidden;
}
#contents-area {
--padding: 20px;
padding: var(--padding);
width: calc(100vw - 2 * var(--padding));
height: calc(100vh - 2 * var(--padding));
font-size: 32px;
display: flex;
align-items: center;
justify-content: center;
}
#contents-area.dropped {
font-size: 12px;
display: flex;
align-items: start;
justify-content: start;
}
</style>
</head>
<body>
<div id="contents-area">
Drop file here
</div>
<script src="file-drop-zone.js"></script>
<script>
const contentsElement = document.getElementById("contents-area");
const dropZone = new FileDropZone(document.body);
dropZone.onFile(contents => {
contentsElement.classList.add("dropped");
contentsElement.innerText = contents;
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment