😎
IntersectionObserverを使うときに、複数作っても大丈夫?と悩んだのでメモ
observer = new IntersectionObserver はいくつも作れます!
コーディング練習でPhotoshopカンプからのコーディングを練習していたときに、
少し悩みました。
でも、よく考えたら、ふつうにつくれるでしょうということのような気もしますが、
ぼくの勉強も含めて記事にしようと思いました。
やりたかったこと
1つのページの中で、交差オブザーバーを使って、以下の2つを付けたいと思いました。
- ある程度スクロールしてきたらヘッダー出現
- スクロールに合わせて、タイトルや画像が入ってくる、よくあるやつ
最初にヘッダーの出現をIntersectionObseverを使って実装していました。
その後、スクロールに合わせてのアニメーションはお手軽なAOSにしようとしました。
すると、まだきちんと確認していないのですが、競合してしまっているような感じがしました。
なので、すべてのアニメーションをIntersectionObseverを使おうとしました。
ちがうアニメーションをつけたい。
ということで、オブザーバーのインスタンス(?)を2つ作りたいなと思ったのですが、
ふと、
「2つ作っても大丈夫なのか?」と
疑問に感じたので、調べてみようと思い立ったしだいです。
検索してみた
「IntersectionObsever 複数」などで検索すると
「複数要素を監視」の記事が多くて、Observerインスタンスを2つ作れるのか、
複数のインスタンスを作って、違うコールバック関数を使いたいという例が出てきません。
でも、よくよく考えてみれば、
インスタンスなのだから、いくつか作っても全くOKってあとで気づいた次第です。
解決して書いたコード
// ヘッダーが現れるときのアクション
// これはある程度スクロールしたらクローンのヘッダーが上からスライドダウンしてくるアニメーションを付けています。
const options = {
rootMargin: "80%",
threshold: 1.0,
};
const headerObserver = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (!e.isIntersecting) {
headerClone.classList.add("clone-open");
}
if (e.isIntersecting) {
headerClone.classList.remove("clone-open");
}
});
}, options);
headerObserver.observe(mv);
// タイトルアニメーション
// これは各セクションのタイトルが見えたら、左からシュッと入ってくるアニメーション
const titleObserver = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting && !e.target.classList.contains('slideLeft')) {
console.log(e.target);
e.target.classList.add("slideLeft");
}
});
});
const animateTitles = document.querySelectorAll('.c-section__heading-block');
animateTitles.forEach((t)=>{
titleObserver.observe(t);
})
// 画像のアニメーション
// いくつかの画像に下からシュッと出現するアニメーション
const imageObserver = new IntersectionObserver((entries)=>{
entries.forEach((e)=>{
if (e.isIntersecting && !e.target.classList.contains('fadeUp')) {
console.log(e.target);
e.target.classList.add("fadeUp");
}
})
})
const animateImages = document.querySelectorAll('.js-animate-image');
animateImages.forEach((t)=>{
console.log(t.target);
imageObserver.observe(t);
})
今後のこと
パフォーマンス的にどうなのだろうかというところは今後の課題。
Obseverインスタンスを1つにして、
その中のコールバック関数で、
要素の種類に応じて、違うアニメーションをつけるとかいう方法もあるのだろうか、
とかぼんやり考えています。
Discussion