Load an image on click and show placeholder, success, and error states
On each button click, load an image into a container. While it loads, show a grey placeholder; on successful load, display the image; on failure, show a red error background. A second click replaces whatever is there. Use the image element's load lifecycle events.
function onButtonClick(container, src) {
// your code here
}
Write the implementation.
Clear the container (replaceChildren()), create an img, set its placeholder background grey, and attach handlers BEFORE setting src: img.onload reveals the image, img.onerror sets a red background. Setting src last kicks off the load, firing exactly one of the two events. Clearing first means a second click replaces the previous result.
- ✗Setting
srcbefore attachingonload/onerror, risking a missed event on a cached image - ✗Expecting image loading to be synchronous (reading
completeright aftersrc) instead of event-driven - ✗Forgetting to clear the container first, so clicks stack images instead of replacing them
- →Why attach
onload/onerrorbefore assigningsrc? - →Which event fires when the image URL is broken, and which on success?
Solution
Attach onload/onerror before setting src, which starts the load.
function onButtonClick(container, src) {
container.replaceChildren(); // replace the previous result
const img = document.createElement('img');
img.style.backgroundColor = 'grey'; // placeholder while loading
img.onload = () => {
img.style.backgroundColor = '';
console.log('loaded');
};
img.onerror = () => {
img.style.backgroundColor = 'red';
};
img.src = src; // starts the load — exactly one event will fire
container.append(img);
}
How it works
Image loading is asynchronous and event-driven, not synchronous. So the onload and onerror handlers are attached BEFORE assigning src: the assignment itself starts the load, and registering the listeners afterwards risks missing the event for a cached image.
The grey background acts as a placeholder while the image loads. On success onload removes it; on a broken URL onerror fires and sets a red background. replaceChildren() at the start ensures a second click replaces the previous result rather than appending another image. </content>