Simple Drag & Drop File Upload Interface with HTML, CSS & JavaScript
In this tutorial, you'll create a "drag and drop" file upload form using HTML, CSS & JavaScript. This makes use of the HTML Drag & Drop API.
Video Tutorial
Source Code
You can find the source code for this video below. Alternatively, browse it on CodePen.
<!DOCTYPE html> <head> <title>Drag and Drop File Upload</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta charset="utf-8"> <link rel="shortcut icon" href="/assets/favicon.ico"> <link rel="stylesheet" href="./src/main.css"> </head> <body> <div class="drop-zone"> <span class="drop-zone__prompt">Drop file here or click to upload</span> <input type="file" name="myFile" class="drop-zone__input"> </div> <script src="./src/main.js"></script> </body>
.drop-zone { max-width: 200px; height: 200px; padding: 25px; display: flex; align-items: center; justify-content: center; text-align: center; font-family: "Quicksand", sans-serif; font-weight: 500; font-size: 20px; cursor: pointer; color: #cccccc; border: 4px dashed #009578; border-radius: 10px; } .drop-zone--over { border-style: solid; } .drop-zone__input { display: none; } .drop-zone__thumb { width: 100%; height: 100%; border-radius: 10px; overflow: hidden; background-color: #cccccc; background-size: cover; position: relative; } .drop-zone__thumb::after { content: attr(data-label); position: absolute; bottom: 0; left: 0; width: 100%; padding: 5px 0; color: #ffffff; background: rgba(0, 0, 0, 0.75); font-size: 14px; text-align: center; }
document.querySelectorAll(".drop-zone__input").forEach((inputElement) => { const dropZoneElement = inputElement.closest(".drop-zone"); dropZoneElement.addEventListener("click", (e) => { inputElement.click(); }); inputElement.addEventListener("change", (e) => { if (inputElement.files.length) { updateThumbnail(dropZoneElement, inputElement.files[0]); } }); dropZoneElement.addEventListener("dragover", (e) => { e.preventDefault(); dropZoneElement.classList.add("drop-zone--over"); }); ["dragleave", "dragend"].forEach((type) => { dropZoneElement.addEventListener(type, (e) => { dropZoneElement.classList.remove("drop-zone--over"); }); }); dropZoneElement.addEventListener("drop", (e) => { e.preventDefault(); if (e.dataTransfer.files.length) { inputElement.files = e.dataTransfer.files; updateThumbnail(dropZoneElement, e.dataTransfer.files[0]); } dropZoneElement.classList.remove("drop-zone--over"); }); }); /** * Updates the thumbnail on a drop zone element. * * @param {HTMLElement} dropZoneElement * @param {File} file */ function updateThumbnail(dropZoneElement, file) { let thumbnailElement = dropZoneElement.querySelector(".drop-zone__thumb"); // First time - remove the prompt if (dropZoneElement.querySelector(".drop-zone__prompt")) { dropZoneElement.querySelector(".drop-zone__prompt").remove(); } // First time - there is no thumbnail element, so lets create it if (!thumbnailElement) { thumbnailElement = document.createElement("div"); thumbnailElement.classList.add("drop-zone__thumb"); dropZoneElement.appendChild(thumbnailElement); } thumbnailElement.dataset.label = file.name; // Show thumbnail for image files if (file.type.startsWith("image/")) { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { thumbnailElement.style.backgroundImage = `url('${reader.result}')`; }; } else { thumbnailElement.style.backgroundImage = null; } }
If you have any questions about this code, please leave a comment on the video.
Comments
Post a Comment