スクロール連動でcomponent監視してwindowの真ん中にきたら連動させたいとかよくありますよね。
毎回やり方忘れるのですが、Observer api使うやり方の忘備録です。
こんなやつ
See the Pen Untitled by yuito118 (@yuito118) on CodePen.
考え方
- 監視対象のhtml要素にidを持たせる
- 連動させたいものにも
${id}-linked
みたいなidを持たせる - observer apiに渡す。
- 検知されたときに${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) のようなものです。この値はパーセント値にすることができます。この一連の値は、交差を計算する前にルート要素の範囲のボックスの各辺を拡大または縮小させることができます。既定値はすべてゼロです。
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全画面になっているのでこれを真ん中に縮小してあげれば良いです。