Swiper.js実装

by interlife

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css"/>
<script src="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

<div class="container">
  <h2>1. 基本のスライダー</h2>
  <div class="swiper main-slider">
    <div class="swiper-wrapper">
      <div class="swiper-slide"><img src="https://placehold.jp/24/3366ff/ffffff/800x400.png?text=Slide1" alt="Slide 1"></div>
      <div class="swiper-slide"><img src="https://placehold.jp/24/ff6633/ffffff/800x400.png?text=Slide2" alt="Slide 2"></div>
      <div class="swiper-slide"><img src="https://placehold.jp/24/33cc66/ffffff/800x400.png?text=Slide3" alt="Slide 3"></div>
    </div>
    <div class="swiper-pagination"></div>
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
  </div>

  <hr>

  <h2>2. モーダル連携(サムネイル)</h2>
  <ul class="thumb-list">
    <li class="js-modal-open" data-modal-index="0">
      <img src="https://placehold.jp/24/3366ff/ffffff/200x200.png?text=1" alt="Thumb 1">
      <p>クリックで1枚目を開く</p>
    </li>
    <li class="js-modal-open" data-modal-index="1">
      <img src="https://placehold.jp/24/ff6633/ffffff/200x200.png?text=2" alt="Thumb 2">
      <p>クリックで2枚目を開く</p>
    </li>
    <li class="js-modal-open" data-modal-index="2">
      <img src="https://placehold.jp/24/33cc66/ffffff/200x200.png?text=3" alt="Thumb 3">
      <p>クリックで3枚目を開く</p>
    </li>
  </ul>

  <div id="modal" class="modal-container">
    <div class="modal-overlay js-modal-close"></div>
    <div class="modal-content">
      <div class="swiper modal-slider">
        <div class="swiper-wrapper">
          <div class="swiper-slide"><img src="https://placehold.jp/24/3366ff/ffffff/800x600.png?text=Full+Slide+1" alt=""></div>
          <div class="swiper-slide"><img src="https://placehold.jp/24/ff6633/ffffff/800x600.png?text=Full+Slide+2"...

SCSS

// 基本レイアウト
.container {
  max-width: 800px;
  margin: 40px auto;
  padding: 0 20px;
  font-family: sans-serif;
}

img {
  width: 100%;
  height: auto;
  display: block;
}

// 1. メインスライダーのカスタマイズ
.main-slider {
  width: 100%;
  border-radius: 8px;
  overflow: hidden;

  // 矢印ボタンのカスタマイズ例
  .swiper-button-next,
  .swiper-button-prev {
    &::after {
      font-size: 24px;
      color: #fff;
      text-shadow: 0 0 5px rgba(0,0,0,0.5);
    }
  }
}

// 2. サムネイルリスト
.thumb-list {
  display: flex;
  gap: 20px;
  list-style: none;
  padding: 0;
  
  li {
    width: 33.3%;
    cursor: pointer;
    transition: opacity 0.3s;
    &:hover { opacity: 0.7; }
    p { font-size: 12px; text-align: center; }
  }
}

// 3. モーダル
.modal-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s;

  &.is-active {
    opacity: 1;
    pointer-events: auto;
  }

  .modal-overlay {
    position: absolute;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.8);
  }

  .modal-content {
    position: relative;
    width: 90%;
    max-width: 900px;
    background: #fff;
    padding: 10px;
    border-radius: 4px;
  }

  .modal-close-btn {
    position: absolute;
    top: -40px;
    right: 0;
    background: none;
    border: none;
    color: #fff;
    font-size: 40px;
    cursor: pointer;
  }
}

JavaScript

$(function () {
  // 1. メインスライダー
  // 分岐をなくし、常にPC用の設定(1枚表示)で動かします
  const mainSwiper = new Swiper('.main-slider', {
    slidesPerView: 1,
    loop: true, // スライドをループさせる
    autoplay: {
      delay: 5000, // 5秒ごとに自動再生
    },
    pagination: { 
      el: '.swiper-pagination', 
      clickable: true 
    },
    navigation: { 
      nextEl: '.swiper-button-next', 
      prevEl: '.swiper-button-prev' 
    }
  });


  // 2. モーダル用スライダー
  const modalSwiper = new Swiper('.modal-slider', {
    loop: true,
    navigation: {
      nextEl: '.swiper-button-next',
      prevEl: '.swiper-button-prev',
    },
  });

  // 3. モーダル開閉イベント
  $('.js-modal-open').on('click', function() {
    const slideIndex = $(this).data('modal-index');
    
    // ループモードに対応した移動メソッド
    modalSwiper.slideToLoop(slideIndex, 0); 
    $('#modal').addClass('is-active');
  });

  $('.js-modal-close').on('click', function() {
    $('#modal').removeClass('is-active');
  });
});