Blog スタッフブログ

サイドバーのスクロール追従を実現するプラグイン『sticky-sidebar.js』

Category | Blog
/ 480views

こんにちは。デザイナーの山田です。
最近めっきり気温が下がってまいりました。秋を通り過ぎて冬の気配を感じるこの頃ですが、皆様いかがお過ごしでしょうか。
近年はこうした異常気象が多いですね。地球温暖化の影響なのかもしれません。個人的な好みですが、秋は好きな季節ですが、冬は寒くて苦手な季節です。来年はじっくりと秋を楽しめたらと思います。

さて、今回はjavaScriptプラグインのご紹介です。
最近実務でもよく使用していたものだったので、振り返りも兼ねてまとめてみました。

Table of contents

  1. 「sticky-sidebar.js」とは
  2. インストール・基本的な使い方
  3. レスポンシブに対応する
  4. メインコンテンツ内の要素と連動させる
  5. おわりに

「sticky-sidebar.js」とは

sticky-sidebarはサイドバーのスクロール追従を実現できるプラグインです。
サイドバーを追従させる方法は、cssのposition: sticky;でも対応できますが、ブラウザによっては使用できなかったり等、いくつかの制約がありました。

その点、このプラグインでは比較的簡単な記述・設定で実装することができ、そのわかりやすさが大きなメリットとなるかと思います。IE11環境やjQueryなしでも動作するので、その点もありがたいですね。

インストール・基本的な使い方

それでは具体的な使い方について触れていきます。
下準備として、ファイルを設置してそのまま読み込みにいくか、npmでインストールしてください。

<script src="sticky-sidebar.min.js"></script>
npm
npm install sticky-sidebar --save

デモとして下記のようなHTMLを組んでみました。
.main.sidebar.wrapperによってflexで横並びとなる関係性となっています。
.sidebarの中にはinnerとなる要素が必要になるので注意が必要です。

<div class="wrapper">

  <main class="main">
    <!-- MainContents -->
  </main>

  <aside class="sidebar">
    <div class="sidebar-inner">
        <!-- SidebarContents -->
    </div>
  </aside>

</div>

あとはプラグインの設定をするだけです。
containerSelectorには先程の.wrapperにあたる要素のclassを、innerWrapperSelectorには.sidebar-innerにあたるclassを記述してください。
またオプションとして、追従中の上下の余白をそれぞれtopSpacing, bottomSpacingで設定できます。

const sidebar = new StickySidebar('.sidebar', {
  containerSelector: '.wrapper',
  innerWrapperSelector: '.sidebar-inner',
  topSpacing: 60,
  bottomSpacing: 0
});

レスポンシブに対応する

実務的・応用的な使用方法も併せてご紹介します。
スクロール追従はPCで閲覧時には有効的な方法となりますが、スマートフォンでサイトを閲覧する際などはそうではありません。そのため、PC時とそれ以外で処理を分ける必要が出てきます。
これは、「画面幅がある一定値より小さくなったときに無効化する〜」といった記述で対策が可能です。

// 実装例
window.addEventListener('resize', () => {
  if(window.outerWidth < 992) {
    sidebar.destroy();
  } else {
    sidebar.initialize();
});

メインコンテンツ内の要素と連動させる

また、サイドバー内の要素が目次などであった場合、現在表示されているメインコンテンツと紐付けて何か処理をしたいケースが多々起こり得ます。
色々と方法はあると思うのですが、私はこちらのサイトを参考にIntersection Observer APIで対応していました。

const areas = document.querySelectorAll('.js-index__area');
  const options = {
    root: null,
    rootMargin: '-50% 0px',
    threshold: 0
  };
  const observer = new IntersectionObserver(doWhenIntersect, options);
  areas.forEach(area => {
    observer.observe(area);
  });
  /**
  * 交差したときに呼びだす関数
  * @param entries
  */
  function doWhenIntersect(entries) {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        activateIndex(entry.target);
      }
    });
  }
  /**
  * 目次の色を変える関数
  * @param element
  */
  function activateIndex(element) {
    const currentActiveIndex = document.querySelector('#js-index__list .is-active');
      if(currentActiveIndex !== null) {
        currentActiveIndex.classList.remove('is-active');
      }
    const newActiveIndex = document.querySelector(`a[href='#${element.id}']`);
    newActiveIndex.classList.add('is-active');
  }

おわりに

サイドバーのスクロール追従は最近よく見る実装・デザインでしたが、初見ではどのように構築していけばよいか、中々イメージがしづらいものだと思います。
その点、今回紹介させていただいたプラグインは非常にシンプルなつくりとなっておりますので、今後の実務でも上手く活かしていけそうです。
この記事が少しでも皆様の参考になれば幸いです。

今回参考にさせていただいた記事

JSでのスクロール連動エフェクトにはIntersection Observerが便利

Category | Blog
Author | Masaki Yamada / 480views

Company information

〒650-0024
神戸市中央区海岸通5 商船三井ビルディング4F

Contact us

WEBに関するお問い合わせは
078-977-8760 (10:00 - 18:00)