Intersection illustration (with shadow root)
by Julien Roche
HTML
<body class="main">
<section class="main__gallery">
<template shadowrootmode="open">
<style>
.main__gallery__item {
border: 1px solid black;
height: 150px;
margin: 10px 0px 10px 0px;
width: 150px;
}
</style>
<img class="main__gallery__item" data-src="http://www.petmd.com/sites/default/files/scared-kitten-shutterstock_191443322.jpg">
<img class="main__gallery__item" data-src="http://www.petmd.com/sites/default/files/scared-kitten-shutterstock_191443322.jpg">
<img class="main__gallery__item" data-src="http://www.petmd.com/sites/default/files/scared-kitten-shutterstock_191443322.jpg">
<img class="main__gallery__item" data-src="http://www.petmd.com/sites/default/files/scared-kitten-shutterstock_191443322.jpg">
<img class="main__gallery__item" data-src="http://www.petmd.com/sites/default/files/scared-kitten-shutterstock_191443322.jpg">
<img class="main__gallery__item" data-src="http://www.petmd.com/sites/default/files/scared-kitten-shutterstock_191443322.jpg">
</template>
</section>
</body>
CSS
html {
height: 100%;
width: 100%;
}
.main {
align-items: center;
display: flex;
height: 90vh;
justify-content: center;
}
.main__gallery {
border: 2px solid red;
height: 300px;
overflow: auto;
text-align: center;
width: 300px;
}
JavaScript
'use strict';
function hasDataSrcAttribute(htmlElement) {
return !!htmlElement.getAttribute('data-src');
}
// Remember the list of images
const images = document.querySelector('.main__gallery').shadowRoot.querySelectorAll('.main__gallery__item');
// Put in place the observation
let observer = new IntersectionObserver(
entries => {
let hasDataSrc = entries.find(entry => hasDataSrcAttribute(entry.target));
if (hasDataSrc) {
entries
.filter(entry => hasDataSrcAttribute(entry.target))
.forEach(function (entry) {
if (entry.intersectionRatio > 0) {
// We have to load the image, so no need anymore to observe it
observer.unobserve(entry.target);
// Load the image
entry.target.src = entry.target.getAttribute('data-src');
entry.target.removeAttribute('data-src');
}
});
} else {
// No need anymore the observer: all the images were loaded
observer.disconnect();
}
},
{
// If the image gets within 50px in the Y axis, start the download.
'rootMargin': '50px 0px',
'threshold': 0.01
}
);
// Associated the observer on each images
images.forEach(image => observer.observe(image));