Skip to content

Instantly share code, notes, and snippets.

@fritzy
Last active July 18, 2022 11:03
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fritzy/8700093 to your computer and use it in GitHub Desktop.
Save fritzy/8700093 to your computer and use it in GitHub Desktop.
Use Mutation Observers to place image placeholders (spinners) on loading images within a target element.
//whenever uncached images are added to the dom tree within target,
//replace them with a spinner gif until they're loaded
function replaceImages(target, spinner_src) {
var spinner, observer;
//detect support
if (window.MutationObserver) {
//preload spinner (probably a gif)
//if it's not ready for first use, oh well
spinner = new Image();
spinner.src = spinner_src;
//yay, setup callback for mutations
observer = new MutationObserver(function (mutations) {
//for every mutation
mutations.forEach(function (mutation) {
//for every added element
mutation.addedNodes.forEach(function (node) {
// Check if we appended a node type that isn't
// an element that we can search for images inside,
// like a text node.
if (typeof node.getElementsByTagName !== 'function') {
return;
}
var imgs = node.getElementsByTagName('img');
//for every new image
imgs.forEach(function (img) {
var parent, spinner_clone, onLoadImage;
//if it hasn't loaded yet
if (!img.complete) {
//remeber what it's parent is
parent = img.parentNode;
//clone our preloaded spinner gif
spinner_clone = spinner.cloneNode();
//replace the not-yet-loaded image with a spinner
parent.replaceChild(spinner_clone, img);
onLoadImage = function (event) {
//the image has loaded so replace the spinner back with the image
parent.replaceChild(spinner_clone, img);
//this event will never fire again. might as well clean it up
event.target.removeEventListener('load', onLoadImage);
};
//when the image is done loading, call the function above
img.addEventListener('load', onLoadImage);
}
});
});
});
});
//bind mutation observer to a specific element (probably a div somewhere)
observer.observe(target, {childList: true, subtree: true});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment