Intersection Observerを使ってみた

JavaScriptのIntersection Observerが便利じゃないのか?と気づき、ちょっと利用しました。

Intersection Observerとは

直訳すると、「交差点の監視」という意味でしょうか。

Intersection Observerの何が便利かというと、対象物が画面に入る時に処理を実行することができます。

この辺の処理はスクロールイベントで頑張ることが多かったのではないでしょうか?

そこが楽になります。

できることとして、例によく出るのですが、

  • 画像の遅延読み込み
  • 無限スクロール

の実装が楽になります。

なぜなら、これ系の処理は画面に入るまでは実行しなくてもいいからです。

今まではライブラリに頼ることが多かったと思いますが、自前でも簡単に作ることができます。

画像の遅延読み込みのライブラリで、layzr.jsはIntersection Observerを利用して、コード数を削減しています。

実装のサンプルコードとして、Vueで無限スクロールを実装したコードを置いておきます。

余談

この作者のライブラリには、他にもIntersection Observerを利用しているので、好きなのか、便利さにはまっているのかなって気持ちになりました。

使い方

const io = new IntersectionObserver((entries) => {
  for (let entry of entries) {
    console.log(entry);
  }
});
io.observe(target);

これでターゲットが画面に表示するかどうかで判定処理が動きます。

実装のサンプルコード

検索結果の無限スクロールです。

loadingとかはないので、形だけです。

export default class SearchScroll {
  constructor(list) {
    this.list = list
    this.page = 2

    const parser = document.createElement('a')
    parser.href = location.href
    this.parser = parser
  }

  path() {
    const params = {
      page: this.page
    }
    const query = $.param(params)
    return `${this.parser.pathname}.json${this.parser.search}&${query}`
  }

  target() {
    return this.list.children[this.list.children.length - 1]
  }
}
import axios from 'axios'
import SearchScroll from './search_scroll.js'

  mounted() {
    const self = this
    const list = document.querySelectorAll(`[data-sentinel]`)[0])
    const searchScroll = new SearchScroll(list)

    const sentinelListener = (entries) => {
      const entry = entries[0]
      if(entry.intersectionRatio > 0) {
        io.unobserve(entry.target)←対象に入ったら前の監視をやめる
        axios.get(searchScroll.path(), {
          headers: {
            'Content-Type': 'application/json'
          }
        })
        .then((response) => {
          searchScroll.page += 1
          self.lists.push(...response.data)
          io.observe(searchScroll.target())←新しい監視を始める
          console.log("success")
        })
        .catch((error) => {
          console.log("fail")
        })
      }
    }

    const io = new IntersectionObserver(sentinelListener)
    io.observe(searchScroll.target())
  }

感想

画面に表示しているかどうかってのいうのは、今後フロントエンドで処理をする上で何かで使いそうなので、覚えておきたい。

細かい制御もできるので、その辺の理解をきちんとしたい。

参考

Intersection Observer を用いた要素出現検出の最適化

Intersection Observer

Intersection Observer が良さそうなので試してみた