As I couldn't find an existing IntersectionObserver
library for Vue 3, I am planning to create my own custom solution.
After researching about directives, it seems like the right approach. (?)
This is my local directive:
directives: {
'lazyload': {
mounted(el) {
if ('IntersectionObserver' in window) {
let intersectionObserver = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const lazyImage = entry.target;
// set data-srcset as image srcset
lazyImage.srcset = lazyImage.getAttribute('data-srcset');
// add class after image has loaded
lazyImage.addEventListener('load', () => {
lazyImage.classList.add('is-lazyloaded');
});
// unobserve after
lazyLoadItemObserver.unobserve(lazyImage);
}
});
});
// observe every image
const lazyLoadItems = document.querySelectorAll('[lazyload]')
lazyLoadItems.forEach((lazyImage) => {
lazyLoadItemObserver.observe(lazyImage);
});
}
}
}
}
The traditional method would involve creating an array of all <IMG>
elements with the attribute
lazyload
, for example. However, I'm unsure how to create such an array for <IMG>
elements with the v-lazyload
binding.
I want a directive that establishes a single IntersectionObserver
observing an array of images with the v-lazyload
binding.