テンプレート

その他

スクロールで「フワッ」と表示【rootMargin版】

更新日:2024-07-12

◆スクロールで「フワッ」と表示をさせる機能 【rootMargin版】

スクロールをしていくと、ブロック毎にフワッと表示される機能になります。

本ページでは、IntersectionObserverrootMarginプロパティを使い、画面の「rootMargin」範囲内に要素が入ったときにフワッと処理を行います。

「動作範囲を可視化」にチェックを入れると動作範囲が可視化され分かり易くなります。

コード例 - Sample

HTML

▶フワッとさせたい要素(ブロック単位)にclass「fuwa-target」を付ける ▶「fuwa-target」をネスト(入れ子)しないようにする

<div class="example">
 <ul>
  <li class="fuwa-target">タイトル1</li>
  <li class="fuwa-target">タイトル2</li>
  <li class="fuwa-target">タイトル3</li>
  <li class="fuwa-target">タイトル4</li>
  <li class="fuwa-target">タイトル5</li>
  <li class="fuwa-target">タイトル6</li>
  <li class="fuwa-target">タイトル7</li>
  <li class="fuwa-target">タイトル8</li>
  <li class="fuwa-target">タイトル9</li>
 </ul>
</div>

CSS

▶「ふわっとアニメーションに必要」と書かれている部分はアニメーションに必要 ▶アニメーションの内容は必要に応じて変更してください(ここでは「translateY」と「opacity」を使用) ▶「transition」の内容も必要に応じて変更してください

.example>ul{
 display: inline-flex;
 flex-direction: column;
 flex-wrap: nowrap;
}
.example>ul>li{
 display: flex;
 align-items: center;
 height: 5rem;
 padding: 0 2rem;
}
.example>ul>li:nth-child(odd){
 background-color: #deb887;
}
.example>ul>li:nth-child(even){
 background-color: #faebd7;
}
.example .fuwa-target{ /*ふわっとアニメーションに必要*/
 transition: all 1000ms 0s ease-out;
 transform: translateY(20px);
 opacity: 0;
}
.example .fuwa-active{ /*ふわっとアニメーションに必要*/
 transform: translateY(0);
 opacity: 1;
}

JavaScript

▶詳細はコード内に記載していますが要約すると ①「fuwa-target」classを付けた全要素を取得 ②それぞれの要素を「IntersectionObserver」で監視するように設定 ③監視対象の要素が「rootMargin」範囲内に入ったときに時classを追加 ④監視対象の要素が「rootMargin」範囲外のときにclassを削除 ▶監視は続くので、rootMarginに出入りする度に、毎回フワッと処理が入ります ▶フワッと処理を1回で止めたい場合は、「unobserve」を使い監視を解除する必要があります
下記コードの黄色い部分のコメントアウトを外して、解除を実行できるようにする
※可視化処理は含んでいません

<script>
//「fuwa-target」classを付けた要素を取得
const fuwaElem = document.querySelectorAll('.fuwa-target');

//関数の実行
fuwa();

//IntersectionObserverを適用する関数
function fuwa(){
 //IntersectionObserverのオプションを設定//「rootMargin」を設定(数値は左から「top」「right」「bottom」「left」になります ※必ず単位を付けること)//ここでは「top」に-30%「bottom」に-40%を設定し「right」「left」は0pxにしています
 let options = {
  rootMargin: '-30% 0px -40%'
 }

 //IntersectionObserverオブジェクトの生成
 const sOB = new IntersectionObserver(fuwaCallback, options);

 for(let i = 0; i < fuwaElem.length; i++){
  //IntersectionObserverの監視を「fuwa-target」classを付けた要素毎に適用
  sOB.observe(fuwaElem[i]);
 }
}

//IntersectionObserverでのコールバック関数
//引数aには、ターゲットになる要素の情報(交差情報などのオブジェクト配列)
//引数bには、生成したIntersectionObserverオブジェクト情報
function fuwaCallback(a, b){

 //「fuwa-target」classを付けた要素毎にコールバック処理
 a.forEach(function(e){
  let fadeElme = e.target; //ターゲットの要素を取得

  //「rootMargin」の状態を「isIntersecting」の情報から取得
  if(e.isIntersecting){
   //「rootMargin」の範囲内にあるとき「fuwa-active」classを付与
   fadeElme.classList.add('fuwa-active');

   //監視の解除
   //b.unobserve(fadeElme);

  }else{
   //「rootMargin」の範囲外のとき「fuwa-active」classを削除
   fadeElme.classList.remove('fuwa-active');

  }
 });
}
</script>

動作サンプル【sample】

動作例 - Sample

※アニメーション処理で「translateY」に20pxプラスされているので、動作範囲が20px下にずれます

  • タイトル1
  • タイトル2
  • タイトル3
  • タイトル4
  • タイトル5
  • タイトル6
  • タイトル7
  • タイトル8
  • タイトル9