2021.03.13  

【JavaScript】スクロールすると追従するサイドバーの実装方法

JavaScript    

今回はスクロールすると追従するサイドバーの実装方法を紹介します。

このページの右側に実装されているものが見本です。
(PCじゃないとみれませんが...あと仕様変更で消していたらすみません)

スクロールすると、一番下のサイドバーのブロックが追従する仕様となっています。

解説を多めに入れているので、他のサイトにも応用が利くと思います。

HTML
<body>
  <header class="header">
        <!-- ヘッダー内容 -->
  </header>
</body >
<! --サイドバー箇所(中央コンテンツ部分は割愛) -->
<div>
  <div class="side_author">
    <!-- 一つ目のサイドバー -->
  </div> 
  <div class="side_author">
    <!-- 二つ目のサイドバー -->
  </div> 
  <div class="side_category">
    <!-- 三つ目のサイドバー -->
  </div> 
  <div class="side_adv">
    <!-- 追従したいサイドバー(四つ目のサイドバー -->
  </div> 
</div>
CSS
.fixed {
  position: fixed;
  top: 5px;
}
JavaScript
window.onscroll = function () {
  let headerH = document.getElementsByClassName('header')[0].clientHeight; // headerの高さを取得
  let side_authorH = document.getElementsByClassName('side_author')[0].clientHeight; // 一つ目サイドバーの高さを取得
  let side_searchH = document.getElementsByClassName('side_search')[0].clientHeight; // 二つ目のサイドバーの高さを取得
  let side_categoryH = document.getElementsByClassName('side_category')[0].clientHeight; // 三つ目のサイドバーの高さを取得
 // 上で取得した高さを合計する
  let totalH = headerH + side_authorH + side_searchH + side_categoryH;
  // 追従させたい要素のクラス名を取得する
  let side_adv = document.getElementsByClassName('side_adv')[0];

  // 画面に追従するサイドバーの実装
  // 画面の幅が991px以下の場合は実行されないようにする
  if (window.innerWidth >= 991){
    // 追従したいサイドバーのところまできたら追従する
    if (window.pageYOffset >= totalH) {
      // 追従機能に使用するCSSを設定
      side_adv.classList.add('fixed'); 
    } else {
      // 追従が必要無い箇所では追従CSSをはずず
      side_adv.classList.remove('fixed');
    }
  }
}

HTML部分について

下から4行目のクラス side_advを追従させるようにコードを記述していきます。

その他のクラスについては、画面最上部からクラス side_advまでの距離を取得するのに使用します。

CSS 部分について

position: fixed; は、クラス side_advを画面に固定するよう設定するコードです。

top: は、画面の上からどの位置に固定するかを設定するコードです。
top: 5px; とすると画面の最上部から5px下に要素を配置してくれます。
top:意外にも、bottom:left:right:などを必要に応じて利用できます。

このCSSをクラス side_advが画面の最上部にきたタイミングで付与することで、画面に追従するサイドバーの実装を行います。

CSSの付与と、付与するタイミングはJavaScriptで制御します。

JavaScript 部分について

最初の let 部分 headerH、side_authorH、side_searchH、side_categoryH で、それぞれの要素の高さを取得し、それらを全て足して totalH に格納しています。

「totalH 」が イコール「クラス side_advまでの距離」となります。

ちなみに、getElementsByClassName('XXクラス')[0]の [0] はHTMLファイルの中で一番最初に登場した 'XXクラス' を取得するという意味です。
'XXクラス'の2つめがある場合、[1]とすることでその要素を取得できます。

if (window.innerWidth >= 991)

window.innerWidth は現在の画面の幅をピクセル単位で返却してくれるプロパティです。
今回は画面の幅が991px以上の時に、サイドバーを追従させるように設定しています。

    if (window.pageYOffset >= totalH) {
      // 追従機能に使用するCSSを設定
      side_adv.classList.add('fixed'); 
    } else {
      // 追従が必要無い箇所では追従CSSをはずず
      side_adv.classList.remove('fixed');
    }

window.pageYOffset は垂直方向のスクロール量をピクセル単位で返すプロパティです。

スクロール量(画面最上部から現在スクロールした箇所までの距離)がtotalH(クラス side_advまでの距離)を上回った時、CCSがside_advに付与されサイドバーの追従を開始します。

スクロールがtotalHまでの距離に達しいていない場合は、

 side_adv.classList.remove('fixed');

でCCSを外します。

参考
https://blog.teorico.jp/
https://lab.syncer.jp/Web/JavaScript/Snippet/10/
https://proengineer.internous.co.jp/content/columnfeature/12366#3
https://www.sejuku.net/blog/68588
https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByClassName
https://developer.mozilla.org/ja/docs/Web/API/Window/innerWidth
https://lab.syncer.jp/Web/API_Interface/Reference/IDL/Window/pageYOffset/

コメント
現在コメントはありません。
コメントする
コメント入力

名前 (※ 必須)

メールアドレス (※ 必須 画面には表示されません)

送信