JavaScriptのIntersectionObserverでheaderのbackgroundを変更する方法

JavaScript

JavaScriptのIntersectionObserverでheaderのbackgroundを変更する方法を紹介します。

JavaScriptのIntersectionObserverでheaderのbackgroundを変更する手順

  • ScrollObserverクラスを作成してIntersectionObserverを初期化
  • Mainクラスを作成してScrollObserverクラスを活用

ScrollObserverクラスを作成してIntersectionObserverを初期化

class ScrollObserver {
  constructor(els, cb, options) {
    this.els = document.querySelectorAll(els);
    const defaultOptions = {
      root: null,
      rootMargin: '0px',
      threshold: 0,
      once: true,
    };
    this.cb = cb;
    this.options = Object.assign(defaultOptions, options);
    this.once = this.options.once;
    this._init();
  }
  _init() {
    const callback = function (entries, observer) {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          this.cb(entry.target, true);
          if (this.once) {
            observer.unobserve(entry.target);
          }
        } else {
          this.cb(entry.target, false);
        }
      });
    };

    this.io = new IntersectionObserver(callback.bind(this), this.options);

    this.els.forEach(el => this.io.observe(el));
  }

  destroy() {
    this.io.disconnect();
  }
}

Mainクラスを作成してScrollObserverクラスを活用

document.addEventListener('DOMContentLoaded', () => {
  const main = new Main();
});

class Main {
  constructor() {
    this.header = document.querySelector('.header');
    this._observers = [];
    this._init();
  }

  set observers(val) {
    this._observers.push(val);
  }

  get observers() {
    return this._observers;
  }

  _init() {
    this._scrollInit();
  }

  //   headerのbackgroundを変更
  _navAnimation(el, inview) {
    if (inview) {
      this.header.classList.remove('header-bg');
    } else {
      this.header.classList.add('header-bg');
    }
  }

  _destroyObservers() {
    this.observers.forEach(ob => {
      ob.destroy();
    });
  }

  destroy() {
    this._destroyObservers();
  }

  _scrollInit() {
    //   ヘッダー背景の変形
    this.observers = new ScrollObserver(
      '.section-hero',
      this._navAnimation.bind(this),
      { once: false }
    );
  }
}

this.headerのclass名とclassListで指定しているclass名、scrollInit()内のclass名を適宜変更することで使えるようになります。
inviewがisIntersectingで交差したらtrueを返します。

scrollInit()内で、observerを初期化します。