Explain Codes LogoExplain Codes Logo

Preview an image before it is uploaded

javascript
image-preview
blob-urls
memory-management
Anton ShumikhinbyAnton Shumikhin·Sep 7, 2024
TLDR

To preview an image before upload, use FileReader and bind an event listener to the file input. The file will be read as a data URL and set it as the src attribute for an image tag:

document.querySelector('input[type="file"]').onchange = event => { let reader = new FileReader(); // Reading file as a data URL on file change reader.onload = e => document.getElementById('preview').src = e.target.result; // Data URL becomes source for an image tag reader.readAsDataURL(event.target.files[0]); };

For the corresponding HTML:

<input type="file" accept="image/*"/> <img id="preview" alt="Image preview" />

This rapidly shows user-selected image as a preview without uploading it to the server.

Optimizing previews with Blob URLs

Generating blob URLs can be faster and less memory-intensive than using FileReader, especially for larger files. Use the URL.createObjectURL() method to create a blob URL:

document.querySelector('input[type="file"]').onchange = event => { const [file] = event.target.files; // Checking if file exists if (file) { document.getElementById('preview').src = URL.createObjectURL(file); // Just blobs doing blob things } };

Memory resource management

It's important to clean up resources after use to prevent memory leaks. Revoke the blob URL after the image is no longer needed:

const imgPreview = document.getElementById('preview'); imgPreview.onload = () => URL.revokeObjectURL(imgPreview.src); // Housekeeping: blob URLs do not clean themselves up

Handling multiple images

For multiple image previews, iterate over the files array and create previews for each image:

document.querySelector('input[type="file"]').onchange = event => { const fileList = event.target.files; // Existing previews be gone! const previewContainer = document.getElementById('preview-container'); previewContainer.innerHTML = ''; // File looping, not just for DJs for (let file of fileList) { const img = document.createElement('img'); img.src = URL.createObjectURL(file); // Avoid memory leaks like the plague img.onload = () => URL.revokeObjectURL(img.src); previewContainer.appendChild(img); } };

Prepare your HTML for multiple previews:

<input type="file" multiple accept="image/*"/> <div id="preview-container"></div>

Solutions for older browsers

IE does not support FileReader and URL.createObjectURL, but you can use proprietary CSS filter properties with IE-specific script wrapped in HTML conditional comments when required.

Consider performance and user experience

Your users and servers will thank you for showing the selected image preview before sending uploads to the server, saving bandwidth and resources.

In addition, use CSS to ensure that your large image previews don't escape their bounding box:

#preview { max-width: 100%; max-height: 300px; }

Lastly, use semantic HTML for a better UX with your image input and previews. A solid interface is always a win!