const options = { root: null, rootMargin: '0px 0px 30px 0px', threshold: 0 } // IntersectionObserver 를 등록한다. const io = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { // 관찰 대상이 viewport 안에 들어온 경우 image 로드 if (entry.isIntersecting) { console.log(entry); entry.target.src = entry.target.dataset.src; observer.unobserve(entry.target); } }) }, options) // 관찰할 대상을 선언하고, 해당 속성을 관찰시킨다. const images = document.querySelectorAll('.image'); images.forEach((el) => { io.observe(el); })
<div class="example"> <h1 class="title">Scroll Down <span class="arrow">👇</span></h1> <img src="https://picsum.photos/600/400/?random?0" alt="random image" class="image-default"> <img data-src="https://picsum.photos/600/400/?random?1" alt="random image" class="image"> <img data-src="https://picsum.photos/600/400/?random?2" alt="random image" class="image"> <img data-src="https://picsum.photos/600/400/?random?3" alt="random image" class="image"> <img data-src="https://picsum.photos/600/400/?random?4" alt="random image" class="image"> <img data-src="https://picsum.photos/600/400/?random?5" alt="random image" class="image"> <img data-src="https://picsum.photos/600/400/?random?6" alt="random image" class="image"> <img data-src="https://picsum.photos/600/400/?random?7" alt="random image" class="image"> </div>
.example { padding-top: 400px; padding-bottom: 100px; width: 100%; background: #eee; position: relative; } .title { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); } .arrow { display: inline-block; animation: bounce 1s infinite ease; } .image { margin: 20px 0; padding: 20px 0; display: block; height: 100%; min-height: 60px; width: 100%; } .image-default { padding: 20px 0; display: block; width: 100%; }