🌊

Splideで複数スライダーを連動させる実装方法

に公開

はじめに

スライダーライブラリ「Splide」を使って、複数のスライダーを連動させる方法のメモ書き。

完成イメージ

  • 複数のスライダーが画面に表示される
  • 1つの「前へ」「次へ」ボタンで全スライダーが同時に動く
  • 各スライダーの個別操作は無効化されている

実装手順

STEP1: 基本的な複数スライダーの準備

まずは独立した複数のスライダーを作成します。

HTML構造

<test-slider>
  <ul class="list">
    <!-- 1つ目のスライダー -->
    <li class="item">
      <div class="splide" data-slider>
        <div class="splide__track">
          <ul class="splide__list">
            <li class="splide__slide" data-slide>スライダー1 - アイテム1</li>
            <li class="splide__slide" data-slide>スライダー1 - アイテム2</li>
            <li class="splide__slide" data-slide>スライダー1 - アイテム3</li>
          </ul>
        </div>
      </div>
    </li>
    
    <!-- 2つ目のスライダー -->
    <li class="item">
      <div class="splide" data-slider>
        <div class="splide__track">
          <ul class="splide__list">
            <li class="splide__slide" data-slide>スライダー2 - アイテム1</li>
            <li class="splide__slide" data-slide>スライダー2 - アイテム2</li>
            <li class="splide__slide" data-slide>スライダー2 - アイテム3</li>
          </ul>
        </div>
      </div>
    </li>
  </ul>
</test-slider>

JavaScript(基本実装)

import '@splidejs/splide/css/core';
import Splide from '@splidejs/splide';

class Slider extends HTMLElement {
  // スライダーインスタンスを格納する配列
  subSliders: Splide[] = [];
  // スライダー要素を取得
  subSpliderEls = this.querySelectorAll<HTMLElement>('[data-slider]');

  constructor() {
    super();
    
    // 各スライダーを初期化
    this.subSpliderEls.forEach((el) => {
      console.log('スライダー初期化:', el);
      
      const splide = new Splide(el, {
        type: 'loop',      // 無限ループ設定
        perMove: 1,        // 1回で移動するスライド数
        pagination: false, // ページネーション(ドット)を非表示
      });
      
      // スライダーを有効化
      splide.mount();
      
      // 配列に追加して管理
      this.subSliders.push(splide);
    });
  }
}

// カスタム要素として登録
customElements.define('test-slider', Slider);

この段階では、各スライダーは独立して動作します。それぞれのスライダーに矢印ボタンが表示され、個別に操作できる状態です。

STEP2: 連動機能の実装

次に、1つのボタンで全スライダーを制御できるように改良します。

HTML(ボタン追加版)

<test-slider>
  <ul class="list">
    <!-- 上記と同じスライダー構造 -->
    <li class="item">
      <div class="splide" data-slider>
        <!-- スライダー1の内容 -->
      </div>
    </li>
    <li class="item">
      <div class="splide" data-slider>
        <!-- スライダー2の内容 -->
      </div>
    </li>
  </ul>
  
  <!-- 連動操作用のカスタムボタン -->
  <div class="custom-controls">
    <button data-prev-button class="control-btn">← 前へ</button>
    <button data-next-button class="control-btn">次へ →</button>
  </div>
</test-slider>

JavaScript(連動機能付き完全版)

import '@splidejs/splide/css/core';
import Splide from '@splidejs/splide';

class Slider extends HTMLElement {
  subSliders: Splide[] = [];
  subSpliderEls = this.querySelectorAll<HTMLElement>('[data-slider]');
  prevButton: HTMLButtonElement | null = this.querySelector('[data-prev-button]');
  nextButton: HTMLButtonElement | null = this.querySelector('[data-next-button]');

  constructor() {
    super();
    
    this.initializeSliders();
    this.setupEventListeners();
  }

  /**
   * 各スライダーの初期化
   */
  private initializeSliders = (): void => {
    this.subSpliderEls.forEach((el, index) => {
      console.log(`スライダー${index + 1}を初期化:`, el);
      
      const splide = new Splide(el, {
        type: 'loop',         // 無限ループ
        perMove: 1,           // 1スライドずつ移動
        pagination: false,    // ページネーション無効
        arrows: false,        // デフォルトの矢印ボタンを無効
        drag: false,          // ドラッグ操作を無効(統一操作のため)
        keyboard: false,      // キーボード操作も無効
      });
      
      splide.mount();
      this.subSliders.push(splide);
    });
  };

  /**
   * イベントリスナーの設定
   */
  private setupEventListeners = (): void => {
    // 前へボタンのクリックイベント
    this.prevButton?.addEventListener('click', () => {
      this.goToPrevious();
    });

    // 次へボタンのクリックイベント  
    this.nextButton?.addEventListener('click', () => {
      this.goToNext();
    });
  };

  /**
   * 全スライダーを前のスライドに移動
   */
  private goToPrevious = (): void => {
    this.subSliders.forEach((slider, index) => {
      console.log(`スライダー${index + 1}を前に移動`);
      slider.go('<'); // '<'は前のスライドを意味する
    });
  };

  /**
   * 全スライダーを次のスライドに移動
   */
  private goToNext = (): void => {
    this.subSliders.forEach((slider, index) => {
      console.log(`スライダー${index + 1}を次に移動`);
      slider.go('>'); // '>'は次のスライドを意味する
    });
  };
}

customElements.define('test-slider', Slider);

技術的なポイント解説

1. 連動操作の仕組み

// 全スライダーに同じ操作を適用
this.subSliders.forEach((slider) => {
  slider.go('<'); // 前のスライドへ
  // または
  slider.go('>'); // 次のスライドへ
});

go()メソッドの引数:

  • '<' - 前のスライドへ移動
  • '>' - 次のスライドへ移動
  • 数値 - 指定インデックスのスライドへ移動

Discussion