InterSectionOberserver 예제
by ChangJoo Park
HTML
<main>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?1">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?2">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?3">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?4">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?5">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?6">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?7">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?8">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?9">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?10">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?11">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?12">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?13">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?14">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?15">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?16">Hello</div>
<div class="lazy-element" data-url="https://picsum.photos/600/600/?random?17">Hello</div>
</main>
CSS
main {
height: 2000px;
}
.lazy-element {
width: 400px;
min-height: 400px;
border: 1px solid black;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
margin-bottom: .5rem;
transition: all .5s ease-in-out;
background-color: grey;
opacity: 0.8;
}
.lazy-element.visible {
color: white;
opacity: 1;
}
JavaScript
const elements = document.querySelectorAll('.lazy-element')
const config = {
rootMargin: '50px 0px',
threshold: 0.01
};
function preloadImage(url) {
return new Promise((resolve, reject) => {
let image = new Image();
image.load = resolve(url);
image.error = reject;
image.src = url;
})
}
const io = new IntersectionObserver(entries => {
entries.forEach((entry, index) => {
if (entry.intersectionRatio > 0) {
io.unobserve(entry.target);
preloadImage(entry.target.dataset.url)
.then(url => {
entry.target.tagName === 'IMG' ?
entry.target.src = url :
entry.target.style.backgroundImage = 'url(' + url + ')';
entry.target.removeAttribute('data-url');
entry.target.classList.add('visible');
})
.catch(error => console.error(error))
}
})
}, config)
elements.forEach(element => {
io.observe(element)
})