7
I am making a Lazy Loader in pure javascript, currently I put my embed script at the end of the HTML that identifies the images and, if they are not ready (for example loaded from the cache), this changes the image to a lighter placeholder and when the user arrives at the image is loaded the original image.
I wonder if there is a way for me to find img tags while the DOM is loaded, to be able to replace their src by my placeholder even before the request is started by the original image (currently non-ccached requests appear in the inspector as canceled).
I currently use the following at the bottom of the page to find the images.
<script>
const srcs = Array();
const srcSets = Array();
const images = document.querySelectorAll("img");
let isRequired = false;
let index = 0;
for (let i = 0; i < images.length; i++) {
if (!images[i].complete) {
isRequired = true;
srcs.push(images[i].src);
srcSets.push(images[i].srcset);
images[i].src = "placeholder.svg"; /// Usar o placeholder de sua escolha, de preferência um SVG pré conectado
images[i].srcset = "";
images[i].setAttribute("index", index);
index++;
}
}
if (isRequired) {
window.onload = () => {
const script = document.createElement("script");
script.src = "loader.js";
document.querySelector("body").appendChild(script);
};
}
</script>
And the "Loader.js" which is responsible for loading the images as they appear on the screen using the native Intersection Observer API.
const imageLoader = (entries) => {
entries.map((e) => {
if (e.isIntersecting) {
const i = e.target.getAttribute("index");
e.target.src = srcs[i];
e.target.srcset = srcSets[i];
observer.unobserve(e.target);
}
});
};
const observer = new IntersectionObserver(imageLoader, {
threshold: 0.1,
});
const observe = () => {
const images = document.querySelectorAll("img");
for (let i = 0; i < images.length; i++) {
if (images[i].getAttribute("index") !== null) {
observer.observe(images[i]);
}
}
};
observe();
Doing this with pure Javascript is not an easy task, and not even possible with full "perfection". I suggest you take a look at attribute
loading
of the elements<img>
, which allows you to configure the Lazy loading natively. However, it is a recent addition.– Luiz Felipe
Recommend this reading and this.
– Rodolfo .Freire