Drag and Drop Image Files With Preview Using JavaScript
Updated: 13-Jan-2024 / Tags: HTML, CSS and Javascript / Views: 800 - Author: George
Introduction
Hello everyone.
In this tutorial, I am going to show you how to drag and drop image files
from your computer into the browser and get an instant preview using only vanilla JavaScript.
You are going to learn how to use the dragenter, the dragover , the dragleave, and the drop event listeners to drag the files into a designated drop-area and handle them.
Also you will learn how to use the dataTransfer object to access the files being dragged and the fileReader object to read the files and display a live preview of the dragged images.
Live Demo
I have created a live example so you can get a close idea of what you are going to recreate.
- Drag and drop one or more images inside the defined drop area.
- Select one or more images using the Choose File button.
- If you choose anything other than .jpeg, .png, or .gif files, an error will be displayed.
- There is a Remove Image button for each image you select.
- Also the drop area is responsive using the CSS Grid system, so it can be used in a mobile application.
Try it out, play with it.
Project's folder
Let's start the tutorial by creating the exact same files that you see in the below code-block.
/--projects-folder |--index.html |--script.js |--styles.css
The Index file
This HTML code sets up a simple user interface for a drag-and-drop file upload system with instructions, a file input, an error message area, and a container for displaying image previews. JavaScript will handle the functionality associated with file selection, drag-and-drop events, and previewing the selected images.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Drag & Drop files</title>
</head>
<body>
<div id="drop-area">
<p class="instructions">Drag & Drop one or more files or click to select</p>
<p class="instructions">Only .jpeg, .png, .gif images allowed</p>
<input onchange="previewFiles(this.files)" type="file" multiple>
<p class="error"></p>
<div class="preview-container"></div>
</div>
<script src="script.js"></script>
</body>
</html>
Now, let's explain the "drop-area" div element from line 11 to 17.
-
Drop Area Container:
<div id="drop-area"></div>
This is the main container for the drag-and-drop functionality. We will drop files onto this area.
-
Instructions for Users:
<p class="instructions">Drag & Drop one or more files or click to select</p> <p class="instructions">Only .jpeg, .png, .gif images allowed</p>
Two paragraphs providing instructions to users. The first instructs users to drag and drop files or click to select them. The second specifies the allowed file types.
-
File Input:
<input onchange="previewFiles(this.files)" type="file" multiple>
An input element of type "file" is provided for users to select files using the file dialog.
The onchange attribute is set to the previewFiles function, which will be triggered when files are selected. The this.files parameter will give us access to the selected files.
The multiple ... attribute allow us to select more than one files.
-
Error Message Container:
A paragraph element with the class "error" is provided to display error messages, such as when an invalid file type is selected.<p class="error"></p>
The error element is hidden by default in the CSS file by setting the display property to "none".
-
Preview Container:
<div class="preview-container"></div>
Another container, this time for displaying previews of the selected images. We will target this element from the javascript file and populate it with the selected images.
Now let's move to the JavaScript file.
The Javascript file
The Javascript code provides an interface for dragging and dropping image files into a designated drop area. It validates the file types, displays an error if needed, and dynamically creates image previews with options to remove them.
// Select relevant DOM elements using querySelector
let dropArea = document.querySelector("#drop-area");
let previewContainer = document.querySelector(".preview-container");
let error = document.querySelector(".error");
// Define an array of allowed image types
let allowedImageTypes = ["image/jpeg", "image/gif", "image/png"];
// Function to preview files dropped onto the drop area
// Also this function runs we whe selecting files using the
// input file form element.
function previewFiles(files){
// Hide any previous error messages
error.style.display = "none";
// Check each dropped file against the allowed image types
for(let file of files){
if(!allowedImageTypes.includes(file.type)){
// Display an error message for disallowed file types
error.style.display = "block";
error.innerHTML = "Only .jpg, .png, .gif files are allowed";
// Hide the error message after 5 seconds
setTimeout( () => {
error.style.display = "none";
}, 5000);
// Return false to stop processing and prevent image preview
return false;
}
}
// If all files are allowed, proceed to preview each image
for(let file of files){
// Create a FileReader to read the file content
let reader = new FileReader();
// Read the file as a data URL (base64 encoded)
reader.readAsDataURL(file);
// When the browser finishes reading the file, the
// onload event listener will trigger a function.
reader.onload = function(){
// Create an image element..
let image = new Image();
// ..and set its source to the result of FileReader
image.src = this.result;
// Create a container for the image
let imageContainer = document.createElement("div");
imageContainer.setAttribute('class', 'image-container');
imageContainer.appendChild(image);
previewContainer.appendChild(imageContainer);
// Create a paragraph element to display the file name
let imageName = document.createElement("p");
imageName.setAttribute('class', 'info');
imageName.innerHTML = file.name;
imageContainer.appendChild(imageName);
// Create a remove button with an onclick event
// to remove the image
let removeButton = document.createElement("button");
removeButton.setAttribute('class', 'remove-button');
removeButton.setAttribute('onclick', 'removeImage(this.parentElement)');
removeButton.innerText = "Remove image";
imageContainer.appendChild(removeButton);
}
}
}
dropArea.addEventListener('dragenter', ev => {
// Highlighting the drop area's border.
dropArea.classList.add("highlight");
// Preventing the browser's default action.
ev.preventDefault();
});
dropArea.addEventListener('dragover', ev => {
// Highlighting the drop area's border.
dropArea.classList.add("highlight");
// Preventing the browser's default action.
ev.preventDefault();
});
dropArea.addEventListener('dragleave', ev => {
// Remove the border highlight when leaving the drop area
dropArea.classList.remove("highlight");
// Preventing the browser's default action.
ev.preventDefault();
});
// Add a drop event listener to handle dropped files
dropArea.addEventListener('drop', ev => {
// Remove the border highlight when dropping the files
dropArea.classList.remove("highlight");
// Preventing the browser's default action.
ev.preventDefault();
// Using the dataTransfer object to access the files being dragged.
if(ev.dataTransfer.files){
// If there are being files dragged and dropped, we store
// this files in the 'transferredFiles' variable.
let transferredFiles = ev.dataTransfer.files;
// Call the previewFiles function with the dropped files
// to preview them
previewFiles(transferredFiles);
}
});
// Function to remove an image element from the DOM
// when click on the remove image button
function removeImage(element){
element.remove();
}
Let's explain the above Javascript code.
-
Initialization
DOM elements are selected for the drop area, preview container, and error message.
let dropArea = document.querySelector("#drop-area"); let previewContainer = document.querySelector(".preview-container"); let error = document.querySelector(".error");
An array allowedImageTypes is defined to specify the allowed image file types (JPEG, GIF, PNG).
let allowedImageTypes = ["image/jpeg", "image/gif", "image/png"];
-
Preview Files Function
This function is triggered when files are selected or dropped.
function previewFiles(files)
It hides any previous error messages.
error.style.display = "none";
Checks if the selected files are of the allowed types, if not, it displays an error message for 5 seconds
for(let file of files){ if(!allowedImageTypes.includes(file.type)){ error.style.display = "block"; error.innerHTML = "Only .jpg, .png, .gif files are allowed"; setTimeout( () => { error.style.display = "none"; }, 5000); return false; } }
For each valid file, it creates an image preview using the FileReader object and displays it in the preview container along with the file name and a remove button.
for(let file of files){ let reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function(){ let image = new Image(); image.src = this.result; let imageContainer = document.createElement("div"); imageContainer.setAttribute('class', 'image-container'); imageContainer.appendChild(image); previewContainer.appendChild(imageContainer); let imageName = document.createElement("p"); imageName.setAttribute('class', 'info'); imageName.innerHTML = file.name; imageContainer.appendChild(imageName); let removeButton = document.createElement("button"); removeButton.setAttribute('class', 'remove-button'); removeButton.setAttribute('onclick', 'removeImage(this.parentElement)'); removeButton.innerText = "Remove image"; imageContainer.appendChild(removeButton); } }
The FileReader object in JavaScript is used to read the content of files asynchronously. It's commonly used in web development, particularly in scenarios where you need to handle files selected by users, such as reading the contents of an image file for preview, processing text files, or handling other types of files.
reader.readAsDataURL(file): Reads the contents of the specified file as a data URL. This is often used for reading image files to display previews.
reader.onload: Triggered when the reading operation from the browser is successfully completed.
So in our code for each selected file, the FileReader is utilized within a loop. When the file reading operation is complete (onload event), a new Image element is created, and its source is set to the data URL obtained from the FileReader.
This dynamic creation of images allows users to see an instant preview of the selected images within the browser.
To Learn more about the FileReader object visit the MDN website. The FileReader object
-
Event Listeners: dragenter, dragover, dragleave
These events are used to add and remove a visual highlight (highlight class) on the drop area when a user drags files over it.
dropArea.addEventListener('dragenter', ev => { dropArea.classList.add("highlight"); ev.preventDefault(); }); dropArea.addEventListener('dragover', ev => { dropArea.classList.add("highlight"); ev.preventDefault(); }); dropArea.addEventListener('dragleave', ev => { dropArea.classList.remove("highlight"); ev.preventDefault(); });
Let's explain the dragenter, dragover, and dragleave events.
These events are part of the Drag and Drop API in web development. They are used to handle various stages of a drag-and-drop operation when an element is being dragged over another element. Here's an explanation of each event:
dragenter.. triggered when the dragged element enters the target element
dragover.. triggered when the dragged element is being dragged over the target element.
dragleave.. triggered when the dragged element leaves the target element.
-
Event Listeners: drop
Removes the highlight class. Prevents the default behavior of opening the dropped files in the browser. Calls the previewFiles function with the transferred files.
dropArea.addEventListener('drop', ev => { dropArea.classList.remove("highlight"); ev.preventDefault(); if(ev.dataTransfer.files){ let transferredFiles = ev.dataTransfer.files; previewFiles(transferredFiles); } });
The drop event is also part of the Drag and Drop API in web development. It is triggered when the user releases the mouse button to drop a dragged element onto a target element. The drop event is crucial for handling the actual data transfer and performing actions based on the dropped data.
The dataTransfer object is also part of the Drag and Drop API in web development. It provides a way to share data during a drag-and-drop operation, allowing you to transfer information between the dragged element and the drop target.
To learn more about the Drag and Drop API you can visit the MDN website. Drag and Drop API
-
Remove Image Function
This function is triggered when a user clicks the "Remove image" button.
It removes the parent container of the button, effectively removing the associated image preview.function removeImage(element){ element.remove(); }
And we are done with the javascript code. The last file that we have is the styles.css stylesheet.
The CSS file
The CSS code below applies the same styling to our HTML elements as you saw in the live example. Copy the code and paste it into your CSS file
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
font-family: sans-serif;
height: 100%;
color: #555;
background-color: #fff;
}
#drop-area {
border: 2px dashed #ccc;
border-radius: 8px;
padding: 20px;
text-align: center;
cursor: pointer;
min-height: 300px;
margin: 10px;
}
.instructions {
display: block;
margin-bottom: 10px;
font-size: 16px;
color: #555;
}
input{
display: inline-block;
margin-top: 20px;
}
.preview-container{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, auto));
grid-column-gap: 30px;
grid-row-gap: 50px;
margin-top: 50px;
}
.image-container{
padding: 5px;
background-color: #3c4d68;
color: white;
}
.preview-container img{
display: inline-block;
width: 100%;
}
.preview-container .info{
margin-top: 10px;
padding: 10px;
}
.preview-container .remove-button{
display: inline-block;
margin-top: 30px;
border: none;
padding: 8px 20px;
font-size: 16px;
background-color: #d9687c;
color: white;
cursor: pointer;
margin-bottom: 20px;
}
.preview-container .remove-button:hover{
filter: brightness(1.2);
}
.error{
color: #712c2c;
background: pink;
padding: 10px;
margin-top: 30px;
display: none;
}
Summary
And that's it. We saw how to drag and drop files from the operating system into the browser. We used the FileReader object and the dataTransfer object to access the files and create an instant preview.
Also we used the dragenter, the dragover, and the dragleave events to add and remove a border highlight on the drop-area.
If you want to know how to upload multiple images to the server you can read the following article: Preview validate and upload multiple files with javascript AJAX and PHP
Thanks for reading, i hope you find the article helpful.
Please leave a comment if you find any errors, so i can update the page with the correct code.
Source code
You can download the source code and use it in any way you like.
Times downloaded: 91