【JavaScript】要素が可視領域に入ったらフェードイン。
スクロールして、要素が可視領域に入ると次々に表示されるようなページを作りたい。
以前は、
…というスクリプトを自前で書く必要がありました。
でも今は、超便利な "Intersection Observer API" というものが用意されているので、この API を呼び出すことで、前者をブラウザ任せにできます。コードも簡単、動作も軽くなる。いい事ずくめ。
以下のMDNの解説ページに詳しい解説があります。
とりあえず、簡単なサンプル。
上のサンプルは…
…という感じに作ってみたものなので、コードは…
CSS.fi{ opacity:0; /* 不透明度の初期値 0(完全透過)*/ transition : opacity 5s 0.3s; /* opacity値に変更が加えられたら0.3秒待って、5秒掛けて変更値へ遷移。*/ }JavaScript
// クラス .fi を指定した要素をリストアップし、それぞれを監視する window.addEventListener( "load", (event)=>{ let tgts = document.querySelectorAll('.fi'); // クラス .fi な要素を全て取得 let options = { // 監視オプション root : null, // Documentルートに対して位置を計測 rootMargin : '0px', // マージンなし threshold : 0.5 // 対象要素の50%が可視になったら発動させる } tgts.forEach( (tgt)=>{ // それぞれの監視要素に対してオブザーバーを登録 new IntersectionObserver( handler , options).observe(tgt); }); }, false ); // コールバック関数。 // entry.isIntersecting (閾値を超えたら true、超えていなければ false を返す)の値をチェック。 // この例では「閾値を超えたときに、対象要素の opacity を 0(透明)→1(完全不透明)にする」という操作を行っている function handler( entries ){ entries.forEach((entry)=> { if( entry.isIntersecting ){ entry.target.style.opacity = 1; } }); }
opacity の設定値を逆にすれば「見えたらフェードアウト」になります。
※ opacity を 0 にして完全透過にしても要素自体はそこに存在しつづけていて、クリックイベントなどを受信します。
それを避けたいならば「要素を完全透過にしたあと、visibility を hidden にする」と設定しておきます。
.fi{ opacity:1; /* 不透明度の初期値 1(完全不透過)*/ visibility:visible; /* 要素を表示(これはデフォルト値なので設定しなくてもよい)*/ transition : opacity 5s 0.3s, visibility 5.5s; /* opacity値に変更が加えられたら0.3秒待って、5秒掛けて変更値へ遷移。visibility値が変更されたら、5.5秒後に変更値へ遷移。*/ }
// コールバック関数。 // 閾値を超えたときに、対象要素の opacity を 1(不透明)→0(透明)にし、visibilityをhiddenにする function handler( entries ){ entries.forEach((entry)=> { if( entry.isIntersecting ){ entry.target.style.opacity = 0; entry.target.style.visibility = 'hidden'; } }); }
コールバック関数内で利用する、要素の交差状態の変化を表すプロパティは、今回の例の "isIntersecting" (交差したか、していないかを判断する)の他にも幾つか用意されています。詳しくは、以下を参照してください。
コメント