Creating a smooth user experience is a key priority in web development, especially when your site relies on large visuals. While working on my new shiny Klondike Solitaire game, I needed to ensure that the card images loaded in a way that felt natural and didn’t leave users staring at a blank screen. So, I decided to add a simple image preloader that could also show users how much of the image had loaded, using nothing but vanilla JavaScript, HTML, and CSS. Here’s how I did it.
Step 1: Basic Setup
First things first, I created a simple file structure to keep things tidy. Here’s what it looked like:
klondike-preloader/
├── index.html
├── styles.css
└── script.js
This way, I had separate files for the HTML structure, the styling, and the JavaScript logic.
Step 2: Building the HTML Structure
In the HTML file, I set up a button to start the image loading process, a progress bar to show how far along the loading was, and a spot to display the image once it was ready.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Klondike Solitaire Image Preloader</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<button id="load-button">Load Solitaire Image</button>
<div id="progress-bar">
<div id="progress"></div>
</div>
<div id="image-container">
<img id="image" alt="Klondike Solitaire Card" />
</div>
<script src="script.js"></script>
</body>
</html>
Step 3: Styling the Progress Bar and Layout
With the structure in place, I moved on to styling. I wanted the progress bar to stay hidden until the image actually started loading.
styles.css
#progress-bar {
width: 100%;
background: lightgray;
margin-bottom: 10px;
height: 20px;
display: none; /* Hidden at first */
}
#progress {
width: 0%;
height: 100%;
background: green;
}
#image-container {
display: none; /* Also hidden initially */
}
#load-button {
margin-bottom: 10px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
Step 4: Adding JavaScript for Image Loading
Now for the JavaScript! Here’s what I did:
- Triggered Image Loading: Clicking the button starts loading the image.
- Updated the Progress Bar: Showed the bar and adjusted its width as the image loaded.
- Fallback for When Content Length Isn't Available: Used a default size to calculate progress in case the server didn’t provide the total size.
script.js
const progressBar = document.getElementById('progress');
const imageContainer = document.getElementById('image-container');
const imageElement = document.getElementById('image');
const loadButton = document.getElementById('load-button');
// Default fallback size in bytes
const DEFAULT_SIZE_BYTES = 500 * 1024; // 500 KB
function loadImage(url) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
let totalSize = DEFAULT_SIZE_BYTES;
document.getElementById('progress-bar').style.display = 'block';
xhr.onprogress = (event) => {
if (event.lengthComputable) {
totalSize = event.total;
}
const percentComplete = (event.loaded / totalSize) * 100;
progressBar.style.width = percentComplete + '%';
};
xhr.onload = () => {
if (xhr.status === 200) {
const blob = xhr.response;
const objectUrl = URL.createObjectURL(blob);
imageElement.src = objectUrl;
imageContainer.style.display = 'block';
progressBar.parentNode.style.display = 'none';
}
};
xhr.onerror = () => {
console.error('Image loading failed.');
};
xhr.send();
}
loadButton.addEventListener('click', () => {
loadImage('https://example.com/your-image.jpg');
});
Key Points:
-
Used
XMLHttpRequest
to Fetch the Image: Tracked progress withonprogress
and handled the image as ablob
. - Fallback for Default Size: Ensured the progress bar worked even if the server didn’t send the file size.
- Cleaned Up After Loading: Hid the progress bar and showed the loaded image.
Step 5: Testing
After coding, I tested it with different image sizes and adjusted the default size to make sure it provided a realistic loading experience. You can try the code on codepen: https://codepen.io/quantotius/pen/KKOXxqP
Conclusion
And there you have it! A basic, yet effective way to preload images and improve the user experience using vanilla JavaScript. Perfect for a game like Klondike Solitaire where visual feedback is a must. Try it out, and if you get stuck, feel free to ask for help!
Top comments (0)