1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

JavaScriptでスクロールアクションを実装する

Posted at

はじめに

Javascriptを用いてスクロールアクションを実装する

コーディングルール

  • ES6 (EcmaScript2015)以降のモダンな記法を使う
  • 関数をモジュール化して使用する
  • data 属性を使用してDOM要素を取得する

コード(pug, scss)

すでにpugファイルとscssファイルは用意されており、JSファイルを作成する。
この2つのファイルはすでに用意されているもののため割愛。

_scrollAction.pug
.scrollAction
  .scrollAction__inner
    .scrollAction__target.--active
      p.scrollAction__label section 0
      p スクロール連動で残り3つを表示させましょう
    .scrollAction__target(data-selector="scroll-action-target")
      p.scrollAction__label section 1
    .scrollAction__target(data-selector="scroll-action-target")
      p.scrollAction__label section 2
    .scrollAction__target(data-selector="scroll-action-target")
      p.scrollAction__label section 3
_scrollAction.scss
@use 'modules/vars';

.scrollAction {
  display: flex;
  justify-content: center;
  margin-top: 128px;

  &__target {
    width: 400px;
    padding: 64px 0;
    color: vars.$themeWhite;
    text-align: center;
    visibility: hidden;
    background-color: vars.$themeBlack;
    opacity: 0;
    transition: all 0.4s;

    &:not(:first-child) {
      margin-top: 64px;
    }

    &.--active {
      visibility: visible;
      opacity: 1;
    }
  }

  &__label {
    font-family: 'League Gothic', sans-serif;
    font-size: 64px;
    letter-spacing: 0.1em;
  }
}

JSコード解説

全文は最後に記述しています。
まず1つずつ実際のコードの解説をしていきます。

変数の定義

以下の変数は、スクロールアクションの機能を実装するための設定や対象要素を指定します。

const dataSelector = '[data-selector=scroll-action-target]';
const ACTIVE = '--active';

ここでは2つの変数を定義しています。

  • dataSelector:スクロールアクションの対象となる要素を特定するためのセレクタです。
  • ACTIVE:要素がビューポートに表示されたときに追加するCSSクラス名です。

Intersection Observerの設定

Intersection Observer は、要素がビューポートに表示されたかどうかを非同期に監視するためのAPIです。

const config = {
    root: null,
    threshold: 0.1,
};
  • root:監視対象の要素が交差する基準となる要素を指定します。null の場合はビューポートを基準とします。
  • threshold:要素がビューポートの何%表示されたときにコールバックを実行するかを指定します。この場合、要素が10%表示されたときにコールバックが実行されます。

Intersection Observerのコールバック関数

以下の関数は、監視対象の要素がビューポートに表示された際に実行されるものです。

const observerCallback = (entries, observer) => {
    entries.forEach((entry) => {
        const { target } = entry;

        if (entry.isIntersecting) {
            target.classList.add(ACTIVE);
            observer.unobserve(target);
        }
    });
};

この関数内では、監視対象の各要素に対して以下の操作を行います。

  • entry.isIntersecting:要素がビューポートに表示されているかを判断します。
  • target.classList.add(ACTIVE):要素がビューポートに表示されている場合、指定したCSSクラスを追加してスタイルを変更します。
  • observer.unobserve(target):一度スタイルを変更した要素は、これ以上監視しないようにします。

Intersection Observerのインスタンス作成

const observer = new IntersectionObserver(observerCallback, config);

この行では、新しい Intersection Observer のインスタンスを作成しています。
Intersection Observer のコンストラクタは2つの引数を受け取ります:

  • observerCallback:監視対象の要素がビューポートに交差した際に実行されるコールバック関数。
  • config:監視の動作をカスタマイズするための設定オブジェクト。

これにより、observer インスタンスは、指定した設定に基づいて要素の監視を行い、要素がビューポートに交差した際には observerCallback 関数を実行するように設定されます。

要素の監視の開始

targets.forEach((target) => {
    observer.observe(target);
});

ここでは、監視対象の要素(targets)のそれぞれに対して、observer.observe(target) を実行しています。これにより、指定した要素の監視が開始されます。

observe メソッドは、指定した要素を監視対象として追加し、その要素がビューポートに交差するかどうかを非同期に監視します。要素がビューポートに交差した場合、先ほど定義した observerCallback 関数が実行されます。

モジュール化処理を実行し、index.jsでimportする

最終行で下記コマンドを打つことで、モジュール化したJSを外部からimportできるようになり、
それをindex.js でimportしてあげます。

export default scrollAction;
import scrollAction from './modules/scrollAction';

scrollAction();

最終的なJSコード

scrollAction.js
/**
 * スクロールアクション機能を実装する関数
 * @function scrollAction
 */
const scrollAction = () => {
  /**
   * 監視対象のセレクタを指定する文字列
   * @type {string}
   */
  const dataSelector = '[data-selector=scroll-action-target]';

  /**
   * 監視対象となる全てのDOM要素を取得
   * @type {NodeList}
   */
  const targets = document.querySelectorAll(dataSelector);

  /**
   * Intersection Observerの設定
   * @type {IntersectionObserverInit}
   */
  const config = {
    root: null,
    threshold: 0.1,
  };

  /**
   * サブメニューの表示状態を制御するCSSクラス名
   * @type {string}
   */
  const ACTIVE = '--active';

  /**
   * Intersection Observerのコールバック関数
   * @param {IntersectionObserverEntry[]} entries
   * @param {IntersectionObserver} observer
   */
  const observerCallback = (entries, observer) => {
    entries.forEach((entry) => {
      const { target } = entry;

      if (entry.isIntersecting) {
        target.classList.add(ACTIVE);
        observer.unobserve(target);
      }
    });
  };

  /**
   * Intersection Observerを作成
   * @type {IntersectionObserver}
   */
  const observer = new IntersectionObserver(observerCallback, config);

  targets.forEach((target) => {
    observer.observe(target);
  });
};

export default scrollAction;

以上。

1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?