Intersection Observer API

Simple demo to learn Intersection Observer API

by cadenzah

HTML

<html>
<body>
<section class="card-grid" id="target-root">
  <button id="disconnect">Observer 해제</button>
  <div class="card">1</div>
  <div class="card">2</div>
  <div class="card">3</div>
  <div class="card">난 언제 보이니? <br> 알려줘!!</div>
  <div class="card">5</div>
  <div class="card">6</div>
  <div class="card">7</div>
  <div class="card">8</div>
  <div class="card">9</div>
  <div class="card">10</div>
  <div class="card">11</div>
  <div class="card">12</div>
  <div class="card">13</div>
  <div class="card">난 언제 보이니? <br> 알려줘!!</div>
  <div class="card">15</div>
  <div class="card">16</div>
  <div class="card">17</div>
  <div class="card">18</div>
  <div class="card">19</div>
  <div class="card">20</div>
</section>
</body>
</html>

CSS

.card-grid {
  display: flex;
  flex-direction: column;
  align-items: center;
  
  width: 100%;
  height: 350px;
  border: 1px solid black;
  
  overflow: auto;
}

.card {
  display: flex;
  align-items: center;
  
  background-color: skyblue;
  width: 50%;
  height: 100px;
  min-height: 100px;
  margin: 20px;
    
}

JavaScript

// Inspired by katanazero86 (https://velog.io/@katanazero86/Intersection-Observer-API)

const callback = (entries, observer) => {
  // callback 함수는 entries, observer 2개의 매개변수를 가진다.

  // "난 언제 보이니? 알려줘!!"
  /* console.log(Object.keys(entries)) */
  entries.forEach((el) => {
		console.log(`${el.target.textContent} - ${el.isIntersecting}`);
  });
};

const options = {
  root : document.getElementById('target-root'), // 변화를 관찰할 대상 요소
  rootMargin : '-40px', // 대상 요소의 margin 값 설정
  thredhold : 0.5 // 관찰자가 반응할 교차점 백분율 (0 ~ 1 사이 값 지정)
};

// 교차점 백분율을 배열로 지정 가능
// thredhold : [0.5, 1] // 50%, 100% 일때 감지

const observer = new IntersectionObserver(callback, options);
const targetElements = document.querySelectorAll('.card');
const disconnectBtn = document.getElementById('disconnect');
disconnectBtn.addEventListener('click', () => {
	console.log('Observer 작동 중지');
	observer.disconnect();
});

// Observer에 최초 등록시에도 callback이 실행된다
// 이후 threshold를 진입할 때 벗어날 때 모두 callback이 실행된다
targetElements.forEach(target => observer.observe(target));