LoginSignup
0
1

More than 1 year has passed since last update.

[js] スクロールに合わせて連動するnavigation

Posted at

スクロール連動でcomponent監視してwindowの真ん中にきたら連動させたいとかよくありますよね。
毎回やり方忘れるのですが、Observer api使うやり方の忘備録です。

こんなやつ

See the Pen Untitled by yuito118 (@yuito118) on CodePen.

考え方

  1. 監視対象のhtml要素にidを持たせる
  2. 連動させたいものにも${id}-linkedみたいなidを持たせる
  3. observer apiに渡す。
  4. 検知されたときに${id}-linkedに.activeをつける

画面の真ん中に来た時を検知するには

まずは仕様の確認。

option

root: null | (Element or Document)

default = null(今見てるwindow)

ターゲットが見えるかどうかを確認するためのビューポートとして使用される要素です。指定されなかった場合、または null の場合は既定でブラウザーのビューポートが使用されます。

rootMargin: DOMString

default = "0px"

root の周りのマージンです。 CSS の margin プロパティに似た値を指定することができます。例えば、"10px 20px 30px 40px" (top, right, bottom, left) のようなものです。この値はパーセント値にすることができます。この一連の値は、交差を計算する前にルート要素の範囲のボックスの各辺を拡大または縮小させることができます。既定値はすべてゼロです。
1.png
2.png

threshold: (double or sequence)

default = 0

単一の数値または数値の配列で、ターゲットがどのくらいの割合で見えている場合にオブザーバーのコールバックを実行するかを示します。見える範囲が 50% を超えたときのみ検出する場合は値 0.5 を使用します。 25% を超える度にコールバックを実行する場合は、 [0, 0.25, 0.5, 0.75, 1] という配列を指定します。既定値は 0 です(つまり、 1 ピクセルでも表示されるとコールバックが実行されます)。 1.0 の値は全てのピクセルが見えるようになるまで、閾値を超えたとはみなされないことを意味します。

実装

const observer = new IntersectionObserver(
  // callback
  (entries) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        // 交差検知
        toggleActive(linkedElement)
      }
    })
  },
  // option
  {
    root: null,
    rootMargin: '-50% 0px',
    threshold: 0,
  }
)

const watch = (id: string) => {
  const section = document.getElementById(id)
  const linkedElement = document.getElementById(`${id}-linked`)
  if (!section || !linkedElement) return

  observer.observe(section)
}

デフォルトの設定{root: null, rootMargin: "0px", threshold: 0}ではwindowに入った瞬間に検知ということですね。
window全画面になっているのでこれを真ん中に縮小してあげれば良いです。
3.png

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1