IntersectionObserver を使ったカレント表示

by minojiro

HTML

<div class="nav">
  <ul>
    <li><a class="navBtn" href="#section1">section1</a></li>
    <li><a class="navBtn" href="#section2">section2</a></li>
    <li><a class="navBtn" href="#section3">section3</a></li>
  </ul>
</div>

<div id="section1" class="section">section1</div>
<div id="section2" class="section">section2</div>
<div id="section3" class="section">section3</div>

CSS

.nav {
  position: sticky;
  top: 0;
}

.section {
  background: #ccffcc;
  text-align: center;
  padding: 500px 0;
  margin-bottom: 20px;
}

.section:nth-child(odd) {
  background: #ffcccc;
}

.navBtn.active {
  color: #f00;
}

JavaScript

const ACTIVE_CLASS_NAME = 'active'
const buttons = document.querySelectorAll('.navBtn');

buttons.forEach(button => {
  const target = document.querySelector(button.getAttribute('href'));
  const observer = new IntersectionObserver(([{isIntersecting}]) => {
    if (isIntersecting) {
      buttons.forEach(el => el.classList.remove(ACTIVE_CLASS_NAME));
      button.classList.add(ACTIVE_CLASS_NAME);
    }
  });
  observer.observe(target);
})