• Brand A

      Item A

      ¥27,500

      ¥19,250

    • Brand B

      Item B

      ¥27,500

      ¥19,250

    • Brand C

      Item C

      ¥27,500

      ¥19,250

    • Brand D

      Item D

      ¥27,500

      ¥19,250

    • Brand C

      Item C

      ¥27,500

      ¥19,250

Libraries

  • Splide v4.1.2

Explanation

Shopifyの有料テーマPrestigeに実装されているスライダーです。

PC/SP共通のメインスライダー、PCの子スライダー、SPのドロワー内のスライダーの3つのスライダーを使用しています。

メイン画像のホットスポットはCSSのカスタムプロパティを指定することで、画像の左上からの位置を指定することができます。

Sample Code

Libraries

<link href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.2/dist/css/splide.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.2/dist/js/splide.min.js"></script>

index.html

<div class="p-slider js-sliderContainer">
  <div class="p-slider__inner">
    <!-- ▼ Popover ▼ -->
    <div class="p-slider__popover js-popover" aria-hidden="true">
      <div class="p-slider__popover-header">
        <button type="button" class="p-slider__popover-header-button u-button-reset js-popoverClose">
          <svg role="presentation" viewBox="0 0 16 14">
            <path d="M15 0L1 14m14 0L1 0" stroke="currentColor" fill="none" fill-rule="evenodd"></path>
          </svg>
        </button>
        <span class="p-slider__popover-header-text">HEADER</span>
      </div>
      <div class="p-slider__popover-body">
        <div class="p-slider__popover-body-inner">
          <!-- ▼ Popover内 商品スライダー ▼ -->
          <div class="splide splide--popover p-slider__popover-slider js-popoverSlider is-overflow is-initialized" role="group" id="splide02">
            <div class="splide__track splide__track--popover" id="splide02-track">
              <ul class="splide__list splide__list--popover p-slider__popover-slider-list" id="splide02-list" style="">
                <li class="splide__slide splide__slide--popover p-slider__popover-slider-slide" id="splide02-slide01">
                  <div class="p-slider__popover-slider-slide-inner">
                    <a href="" class="p-slider__popover-slider-slide-image">
                      <img src="/assets/demos/hotspot-interactive-nested-slider/img/slide01_item01.jpg" alt="" width="400" height="480" class="">
                    </a>
                    <div class="p-slider__popover-slider-detail">
                      <p class="p-slider__popover-slider-brand-name">Brand A</p>
                      <p class="p-slider__popover-slider-product-name">Item A</p>
                      <div class="p-slider__popover-slider-price-wrap">
                        <p class="text-price text-regular-price">¥27,500</p>
                        <p class="text-price text-sale-price">¥19,250</p>
                      </div>
                    </div>
                  </div>
                </li>
                <li class="splide__slide splide__slide--popover p-slider__popover-slider-slide" id="splide02-slide02">
                  <div class="p-slider__popover-slider-slide-inner">
                    <a href="" class="p-slider__popover-slider-slide-image" tabindex="-1">
                      <img src="/assets/demos/hotspot-interactive-nested-slider/img/slide01_item02.jpg" alt="" width="400" height="480" class="">
                    </a>
                    <div class="p-slider__popover-slider-detail">
                      <p class="p-slider__popover-slider-brand-name">Brand B</p>
                      <p class="p-slider__popover-slider-product-name">Item B</p>
                      <div class="p-slider__popover-slider-price-wrap">
                        <p class="text-price text-regular-price">¥27,500</p>
                        <p class="text-price text-sale-price">¥19,250</p>
                      </div>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
          <!-- ▲ Popover内 商品スライダー ▲ -->
        </div>
      </div>
    </div>
    <!-- ▼ 親スライダー ▼ -->
    <div class="splide splide__track--parent p-slider__parent-slider js-parentSlider splide--slide splide--ltr splide--draggable is-active is-overflow is-initialized" role="group" id="splide01" aria-roledescription="carousel">
      <div class="splide__arrows splide__arrows-parent splide__arrows--ltr">
        <button class="splide__arrow splide__arrow-parent splide__arrow--prev splide__arrow-parent--prev" type="button" aria-label="Previous slide" aria-controls="splide01-track">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="40" height="40" focusable="false">
            <path d="m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z"></path>
          </svg>
        </button>
        <button class="splide__arrow splide__arrow-parent splide__arrow--next splide__arrow-parent--next" type="button" aria-label="Next slide" aria-controls="splide01-track" disabled="">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" width="40" height="40" focusable="false">
            <path d="m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z"></path>
          </svg>
        </button>
      </div>
      <div class="splide__track splide__track--parent splide__track--slide splide__track--ltr splide__track--draggable" id="splide01-track" style="padding-left: 0px; padding-right: 0px;" aria-live="polite" aria-atomic="true" aria-busy="false">
        <ul class="splide__list splide__list--parent p-slider__parent-slider-list" id="splide01-list" role="presentation" style="transform: translateX(-2000px);">
          <li class="splide__slide splide__slide--parent p-slider__parent-slider-slide" id="splide01-slide01" role="group" aria-roledescription="slide" aria-label="1 of 3" style="width: calc(100%);" aria-hidden="true">
            <div class="p-slider__parent-slider-slide-inner">
              <div class="p-slider__parent-slider-image-wrapper">
                <img src="/assets/demos/hotspot-interactive-nested-slider/img/slide01_model.jpg" alt="" width="400" height="480">
                <!-- ▼ Hot Spot ▼ -->
                <button type="button" class="p-slider__parent-slider-hot-spot u-button-reset js-hotSpot" style="--hot-spot-top: 63%; --hot-spot-left: 45%;" aria-current="true" tabindex="-1"></button>
                <button type="button" class="p-slider__parent-slider-hot-spot u-button-reset js-hotSpot" style="--hot-spot-top: 52%; --hot-spot-left: 84%;" tabindex="-1"></button>
                <!-- ▲ Hot Spot ▲ -->
              </div>
              <div class="p-slider__parent-slider-products u-hidden-phone">
                <!-- ▼ 子スライダー ▼ -->
                <div class="splide splide--child p-slider__child-slider js-childSlider splide--fade splide--ltr is-active is-overflow is-initialized" role="group" id="splide03" aria-roledescription="carousel">
                  <div class="splide__track splide__track--child splide__track--fade splide__track--ltr" id="splide03-track" style="padding-left: 0px; padding-right: 0px;" aria-live="polite" aria-atomic="true">
                    <ul class="splide__list p-slider__child-slider-list" id="splide03-list" role="presentation">
                      <li class="splide__slide splide__slide--child p-slider__child-slider-slide is-active is-visible" id="splide03-slide01" role="tabpanel" aria-roledescription="slide" aria-label="1 of 2" style="width: calc(100%); transform: translateX(0%);">
                        <div class="p-slider__child-slider-inner">
                          <a href="" class="p-slider__child-slider" tabindex="-1">
                            <img src="/assets/demos/hotspot-interactive-nested-slider/img/slide01_item01.jpg" alt="" width="400" height="480" class="p-slider__child-slider-image">
                          </a>
                          <div class="p-slider__child-slider-detail">
                            <p class="p-slider__child-slider-brand-name">Brand A</p>
                            <p class="p-slider__child-slider-product-name">Item A</p>
                            <div class="p-slider__child-slider-price-wrap">
                              <p class="text-price text-regular-price">¥27,500</p>
                              <p class="text-price text-sale-price">¥19,250</p>
                            </div>
                          </div>
                        </div>
                      </li>
                      <li class="splide__slide splide__slide--child p-slider__child-slider-slide is-next" id="splide03-slide02" role="tabpanel" aria-roledescription="slide" aria-label="2 of 2" style="width: calc(100%); transform: translateX(-100%);" aria-hidden="true">
                        <div class="p-slider__child-slider-inner">
                          <a href="" class="p-slider__child-slider" tabindex="-1">
                            <img src="/assets/demos/hotspot-interactive-nested-slider/img/slide01_item02.jpg" alt="" width="400" height="480" class="p-slider__child-slider-image">
                          </a>
                          <div class="p-slider__child-slider-detail">
                            <p class="p-slider__child-slider-brand-name">Brand B</p>
                            <p class="p-slider__child-slider-product-name">Item B</p>
                            <div class="p-slider__child-slider-price-wrap">
                              <p class="text-price text-regular-price">¥27,500</p>
                              <p class="text-price text-sale-price">¥19,250</p>
                            </div>
                          </div>
                        </div>
                      </li>
                    </ul>
                  </div>
                  <ul class="splide__pagination splide__pagination-child splide__pagination--ltr" role="tablist" aria-label="Select a slide to show">
                    <li role="presentation"><button class="splide__pagination__page splide__pagination-child__page is-active" type="button" role="tab" aria-controls="splide03-slide01" aria-label="Go to slide 1" aria-selected="true" tabindex="-1"></button></li>
                    <li role="presentation"><button class="splide__pagination__page splide__pagination-child__page" type="button" role="tab" aria-controls="splide03-slide02" aria-label="Go to slide 2" tabindex="-1"></button></li>
                  </ul>
                </div>
                <!-- ▲ 子スライダー ▲ -->
              </div>
            </div>
          </li>
          <li class="splide__slide splide__slide--parent p-slider__parent-slider-slide is-prev" id="splide01-slide02" role="group" aria-roledescription="slide" aria-label="2 of 3" style="width: calc(100%);" aria-hidden="true">
            <div class="p-slider__parent-slider-slide-inner">
              <div class="p-slider__parent-slider-image-wrapper">
                <img src="https://placehold.jp/999999/cccccc/400x480.jpg" alt="" width="400" height="480">
                <!-- ▼ Hot Spot ▼ -->
                <button type="button" class="p-slider__parent-slider-hot-spot u-button-reset js-hotSpot" style="--hot-spot-top: 25%; --hot-spot-left: 84%;" aria-current="true" tabindex="-1"></button>
                <button type="button" class="p-slider__parent-slider-hot-spot u-button-reset js-hotSpot" style="--hot-spot-top: 43%; --hot-spot-left: 74%;" tabindex="-1"></button>
                <!-- ▲ Hot Spot ▲ -->
              </div>
              <div class="p-slider__parent-slider-products u-hidden-phone">
                <!-- ▼ 子スライダー ▼ -->
                <div class="splide splide--child p-slider__child-slider js-childSlider splide--fade splide--ltr is-active is-overflow is-initialized" role="group" id="splide05" aria-roledescription="carousel">
                  <div class="splide__track splide__track--child splide__track--fade splide__track--ltr" id="splide05-track" style="padding-left: 0px; padding-right: 0px;" aria-live="polite" aria-atomic="true">
                    <ul class="splide__list p-slider__child-slider-list" id="splide05-list" role="presentation">
                      <li class="splide__slide splide__slide--child p-slider__child-slider-slide is-active is-visible" id="splide05-slide01" role="tabpanel" aria-roledescription="slide" aria-label="1 of 2" style="width: calc(100%); transform: translateX(0%);">
                        <div class="p-slider__child-slider-inner">
                          <a href="" class="p-slider__child-slider" tabindex="-1">
                            <img src="https://placehold.jp/cccccc/999999/400x480.jpg" alt="" width="400" height="480" class="p-slider__child-slider-image">
                          </a>
                          <div class="p-slider__child-slider-detail">
                            <p class="p-slider__child-slider-brand-name">Brand C</p>
                            <p class="p-slider__child-slider-product-name">Item C</p>
                            <div class="p-slider__child-slider-price-wrap">
                              <p class="text-price text-regular-price">¥27,500</p>
                              <p class="text-price text-sale-price">¥19,250</p>
                            </div>
                          </div>
                        </div>
                      </li>
                      <li class="splide__slide splide__slide--child p-slider__child-slider-slide is-next" id="splide05-slide02" role="tabpanel" aria-roledescription="slide" aria-label="2 of 2" style="width: calc(100%); transform: translateX(-100%);" aria-hidden="true">
                        <div class="p-slider__child-slider-inner">
                          <a href="" class="p-slider__child-slider" tabindex="-1">
                            <img src="https://placehold.jp/cccccc/999999/400x480.jpg" alt="" width="400" height="480" class="p-slider__child-slider-image">
                          </a>
                          <div class="p-slider__child-slider-detail">
                            <p class="p-slider__child-slider-brand-name">Brand D</p>
                            <p class="p-slider__child-slider-product-name">Item D</p>
                            <div class="p-slider__child-slider-price-wrap">
                              <p class="text-price text-regular-price">¥27,500</p>
                              <p class="text-price text-sale-price">¥19,250</p>
                            </div>
                          </div>
                        </div>
                      </li>
                    </ul>
                  </div>
                  <ul class="splide__pagination splide__pagination-child splide__pagination--ltr" role="tablist" aria-label="Select a slide to show">
                    <li role="presentation"><button class="splide__pagination__page splide__pagination-child__page is-active" type="button" role="tab" aria-controls="splide05-slide01" aria-label="Go to slide 1" aria-selected="true" tabindex="-1"></button></li>
                    <li role="presentation"><button class="splide__pagination__page splide__pagination-child__page" type="button" role="tab" aria-controls="splide05-slide02" aria-label="Go to slide 2" tabindex="-1"></button></li>
                  </ul>
                </div>
                <!-- ▲ 子スライダー ▲ -->
              </div>
            </div>
          </li>
          <li class="splide__slide splide__slide--parent p-slider__parent-slider-slide is-active is-visible" id="splide01-slide03" role="group" aria-roledescription="slide" aria-label="3 of 3" style="width: calc(100%);">
            <div class="p-slider__parent-slider-slide-inner">
              <div class="p-slider__parent-slider-image-wrapper">
                <img src="https://placehold.jp/cccccc/999999/400x480.jpg" alt="" width="400" height="480">
                <!-- ▼ Hot Spot ▼ -->
                <button type="button" class="p-slider__parent-slider-hot-spot u-button-reset js-hotSpot" style="--hot-spot-top: 25%; --hot-spot-left: 84%;" aria-current="true"></button>
                <!-- ▲ Hot Spot ▲ -->
              </div>
              <div class="p-slider__parent-slider-products u-hidden-phone">
                <!-- ▼ 子スライダー ▼ -->
                <div class="splide splide--child p-slider__child-slider js-childSlider splide--fade splide--ltr is-active is-overflow is-initialized" role="group" id="splide07" aria-roledescription="carousel">
                  <div class="splide__track splide__track--child splide__track--fade splide__track--ltr" id="splide07-track" style="padding-left: 0px; padding-right: 0px;" aria-live="polite" aria-atomic="true">
                    <ul class="splide__list p-slider__child-slider-list" id="splide07-list" role="presentation">
                      <li class="splide__slide splide__slide--child p-slider__child-slider-slide is-active is-visible" id="splide07-slide01" role="tabpanel" aria-roledescription="slide" aria-label="1 of 1" style="width: calc(100%); transform: translateX(0%);">
                        <div class="p-slider__child-slider-inner">
                          <a href="" class="p-slider__child-slider">
                            <img src="https://placehold.jp/cccccc/999999/400x480.jpg" alt="" width="400" height="480" class="p-slider__child-slider-image">
                          </a>
                          <div class="p-slider__child-slider-detail">
                            <p class="p-slider__child-slider-brand-name">Brand C</p>
                            <p class="p-slider__child-slider-product-name">Item C</p>
                            <div class="p-slider__child-slider-price-wrap">
                              <p class="text-price text-regular-price">¥27,500</p>
                              <p class="text-price text-sale-price">¥19,250</p>
                            </div>
                          </div>
                        </div>
                      </li>
                    </ul>
                  </div>
                  <ul class="splide__pagination splide__pagination-child splide__pagination--ltr" role="tablist" aria-label="Select a slide to show">
                    <li role="presentation"><button class="splide__pagination__page splide__pagination-child__page is-active" type="button" role="tab" aria-controls="splide07-slide01" aria-label="Go to slide 1" aria-selected="true"></button></li>
                  </ul>
                </div>
                <!-- ▲ 子スライダー ▲ -->
              </div>
            </div>
          </li>
        </ul>
      </div>
    </div>
    <!-- ▲ 親スライダー ▲ -->
  </div>
  <div class="p-slider__view-buttons u-hidden-desktop">
    <button type="button" class="p-slider__view-button js-viewButton">View Selected Product</button>
  </div>
</div>

style.css

@charset "UTF-8";

:where(.p-slider) img {
  width: 100%;
  height: auto;
}
:where(.p-slider) button {
  color: unset;
  background-color: unset;
  border: none;
}
.p-slider {
  width: min(100%, 1000px);
  margin: 0 auto;
}
.splide__pagination {
  position: static;
  margin-top: 10px;
}
.splide__pagination__page {
  width: 10px;
  height: 10px;
  opacity: 0.4;
  margin: 5px;
  background-color: #000;
}
.splide__pagination__page.is-active {
  opacity: 1;
  background-color: #000;
}
.text-regular-price:has(+ .text-sale-price) {
  text-decoration: line-through;
}
.text-sale-price {
  color: var(--color-red);
}
/* Popover */
.p-slider__popover {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 10;
  transform: translateY(100%);
  width: 100%;
  background-color: var(--color-white);
  visibility: hidden;
  transition: all 0.4s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.p-slider__popover[aria-hidden="false"] {
  transform: translateY(0);
  visibility: visible;
}
.p-slider__popover-header {
  position: relative;
  padding: 13px 20px;
  border-bottom: 1px solid rgb(222 222 222 / 0.4);
  text-align: center;
}
.p-slider__popover-header-button {
  position: absolute;
  top: 50%;
  left: 20px;
  transform: translateY(-50%);
  padding: 10px;
}
.p-slider__popover-header-button svg {
  width: 0.8em;
  height: 0.8em;
}
.p-slider__popover-header-text {
  font-size: 15px;
  font-weight: 500;
}
.p-slider__popover-slider-slide {
  padding: 20px;
}
.p-slider__popover-slider-detail,
.p-slider__child-slider-detail {
  display: flex;
  flex-direction: column;
  row-gap: 5px;
  margin-top: 10px;
}
.p-slider__popover-slider-brand-name,
.p-slider__child-slider-brand-name {
  font-weight: 600;
}
.p-slider__popover-slider-price-wrap,
.p-slider__child-slider-price-wrap {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  column-gap: 5px;
}
/* Parent Slider */
.p-slider__parent-slider-slide {
  cursor: grab;
}
.p-slider__parent-slider-image-wrapper {
  position: relative;
}
.p-slider__parent-slider-hot-spot {
  --hot-spot-active-scale: 1.3;
  position: absolute;
  top: calc(var(--hot-spot-top, 0) - (var(--hot-spot-size) / 2));
  left: calc(var(--hot-spot-left, 0) - (var(--hot-spot-size) / 2));
  z-index: 1;
  transform: scale(1);
  display: inline-block;
  width: var(--hot-spot-size);
  height: var(--hot-spot-size);
  padding: 0;
  line-height: 0;
  background-color: var(--color-white);
  border-radius: 50%;
  box-shadow: 0 1px 10px #00000040;
  transition: transform 0.25s ease-in-out;
}
.p-slider__parent-slider-hot-spot[aria-current="true"] {
  transform: scale(var(--hot-spot-active-scale, 1));
}
@media (hover: hover) {
  .p-slider__parent-slider-hot-spot:hover {
    transform: scale(var(--hot-spot-active-scale, 1));
  }
}
.p-slider__parent-slider-hot-spot::after {
  --hot-spot-bg-size: calc(var(--hot-spot-size) * 3.5);
  content: "";
  position: absolute;
  top: calc(50% - (var(--hot-spot-bg-size) / 2));
  left: calc(50% - (var(--hot-spot-bg-size) / 2));
  width: var(--hot-spot-bg-size);
  height: var(--hot-spot-bg-size);
  border-radius: 50%;
  background-color: rgb(222 222 222 / 0.4);
  animation: 1.4s hotSpotAnimation ease-in-out infinite alternate;
}
/* for mobile device */
@media screen and (max-width: 767px) {
  .u-hidden-phone {
    display: none;
  }
  .p-slider {
    padding: 0 15px;
  }
  /* Parent Slider */
  .p-slider__parent-slider {
    transition:
      transform 0.3s ease-in-out,
      opacity 0.3s ease-in-out;
  }
  .p-slider__parent-slider[data-state="floating"] {
    transform: translate3d(0px, -427px, 0px);
  }
  .p-slider__parent-slider-slide {
    opacity: 0;
    transition: opacity 0.3s ease-in-out;
  }
  .p-slider__parent-slider-slide.is-active {
    opacity: 1;
  }
  .p-slider__parent-slider-hot-spot {
    --hot-spot-size: 16px;
  }
  .splide__arrow-parent--prev {
    left: -0.5em;
  }
  .splide__arrow-parent--next {
    right: -0.5em;
  }
  .p-slider__view-buttons {
    margin-top: 20px;
  }
  .p-slider__view-button {
    display: grid;
    place-items: center;
    width: fit-content;
    min-width: 180px;
    margin: 0 auto;
    padding: 5px 10px;
    color: #fff;
    text-align: center;
    text-decoration: none;
    background-color: var(--color-darkgray);
    border: 1px solid var(--color-darkgray);
    transition: all 150ms ease-in-out;
  }
}
/* for desktop device */
@media screen and (min-width: 768px) {
  .u-hidden-desktop {
    display: none;
  }
  /* Parent Slider */
  .p-slider__parent-slider-slide {
    background-color: var(--color-lightgray);
  }
  .p-slider__parent-slider-slide-inner {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .p-slider__parent-slider-hot-spot {
    --hot-spot-size: 14px;
  }
  .splide__arrow-parent--prev {
    left: -3em;
  }
  .splide__arrow-parent--next {
    right: -3em;
  }
  .p-slider__parent-slider-products {
    display: grid;
    place-content: center;
    width: 50%;
    margin: 0 auto;
  }
  .p-slider__parent-slider-products .splide__pagination {
    top: calc(100% + 52px);
    bottom: unset;
  }
}

@keyframes hotSpotAnimation {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}

index.js

"use strict";

document.addEventListener("DOMContentLoaded", () => {
  setSlider();
});

const setSlider = () => {
  // メディアクエリを作成
  const mediaQuery = window.matchMedia("(min-width: 768px)");

  // 画面幅に応じた処理を行う関数を定義
  const handleMediaQueryChange = (callback) => {
    if (mediaQuery.matches) {
      // 768px以上のときの処理
      callback(true);
    } else {
      // 768px未満のときの処理
      callback(false);
    }
  };

  // 対象要素の取得
  const recommendContainers = document.querySelectorAll(".js-sliderContainer");

  const PARENT_SLIDER_OPTIONS = {
    arrows: true,
    pagination: false,
    classes: {
      // 矢印関連のクラスのカスタマイズ
      arrows: "splide__arrows splide__arrows-parent",
      arrow: "splide__arrow splide__arrow-parent",
      prev: "splide__arrow--prev splide__arrow-parent--prev",
      next: "splide__arrow--next splide__arrow-parent--next",

      // ページネーション関連のクラスのカスタマイズ
      pagination: "splide__pagination splide__pagination-parent",
      page: "splide__pagination__page splide__pagination-parent__page",
    },
    breakpoints: {
      // SP
      767: {
        padding: "var(--container-padding)",
      },
    },
  };

  const CHILD_SLIDER_OPTIONS = {
    arrows: false,
    drag: false,
    type: "fade",
    classes: {
      // 矢印関連のクラスのカスタマイズ
      arrows: "splide__arrows splide__arrows-child",
      arrow: "splide__arrow splide__arrow-child",
      prev: "splide__arrow--prev splide__arrow-child--prev",
      next: "splide__arrow--next splide__arrow-child--next",

      // ページネーション関連のクラスのカスタマイズ
      pagination: "splide__pagination splide__pagination-child",
      page: "splide__pagination__page splide__pagination-child__page",
    },
    breakpoints: {
      // SP
      767: {
        destroy: true,
      },
    },
  };

  const POPOVER_SLIDER_OPTIONS = {
    arrows: false,
    pagination: true,
    type: "loop",
    mediaQuery: "min",
    classes: {
      // 矢印関連のクラスのカスタマイズ
      arrows: "splide__arrows splide__arrows-popover",
      arrow: "splide__arrow splide__arrow-popover",
      prev: "splide__arrow--prev splide__arrow-popover--prev",
      next: "splide__arrow--next splide__arrow-popover--next",

      // ページネーション関連のクラスのカスタマイズ
      pagination: "splide__pagination splide__pagination-popover",
      page: "splide__pagination__page splide__pagination-popover__page",
    },
    breakpoints: {
      // PC
      768: {
        destroy: true,
      },
    },
  };

  recommendContainers.forEach((container) => {
    const popovers = container.querySelectorAll(".js-popover");
    const popoverSliders = container.querySelectorAll(".js-popoverSlider");
    const parentSlider = container.querySelector(".js-parentSlider");
    const parentSlides = parentSlider.querySelectorAll(
      ".splide__slide--parent",
    );
    const viewButtons = container.querySelectorAll(".js-viewButton");

    const parentSliderInstance = new Splide(
      parentSlider,
      PARENT_SLIDER_OPTIONS,
    );
    parentSliderInstance.mount();

    parentSlides.forEach((parentSlide, parentSlideIndex) => {
      const hotSpots = parentSlide.querySelectorAll(".js-hotSpot");

      // Popover内スライダーの初期化
      const popoverSlider = popoverSliders[parentSlideIndex];
      const popoverSliderInstance = new Splide(
        popoverSlider,
        POPOVER_SLIDER_OPTIONS,
      );
      popoverSliderInstance.mount();

      // 子スライダーの初期化
      const childSlider = parentSlide.querySelector(".js-childSlider");

      if (childSlider) {
        const childSliderInstance = new Splide(
          childSlider,
          CHILD_SLIDER_OPTIONS,
        );

        childSliderInstance.mount();

        // メイン画像のホットスポットクリック時に子スライダーを移動
        hotSpots.forEach((hotSpot, hotSpotIndex) => {
          hotSpot.addEventListener("click", (e) => {
            hotSpots.forEach((hotSpot) => {
              hotSpot.setAttribute("aria-current", "false");
            });

            // 画面幅に応じて分岐
            handleMediaQueryChange((isDesktop) => {
              if (isDesktop) {
                // PC
                childSliderInstance.go(hotSpotIndex);
              } else {
                // SP
                const currentPopover = popovers[parentSlideIndex];

                popoverSliderInstance.go(hotSpotIndex);

                popoverSliderInstance.on("moved", () => {
                  parentSlider.dataset.state = "floating";
                  document.body.style.overflow = "hidden";
                  currentPopover.ariaHidden = "false";
                });
              }
            });

            e.target.setAttribute("aria-current", "true");
          });
        });

        // 子スライダーの移動時にホットスポットの状態を更新
        childSliderInstance.on("moved", () => {
          hotSpots.forEach((hotSpot) => {
            hotSpot.setAttribute("aria-current", "false");
          });
          hotSpots[childSliderInstance.index].setAttribute(
            "aria-current",
            "true",
          );
        });
      }

      // ポップオーバーを表示するボタン
      viewButtons.forEach((viewButton) => {
        viewButton.addEventListener("click", () => {
          const currentSlideIndex = parentSliderInstance.index;
          const currentPopover = popovers[currentSlideIndex];
          const sliderSpeed = popoverSliderInstance.options.speed;

          popoverSliderInstance.go(0);

          setTimeout(() => {
            parentSlider.dataset.state = "floating";
            document.body.style.overflow = "hidden";
            currentPopover.ariaHidden = "false";
          }, sliderSpeed);
        });
      });

      // ポップオーバー内の閉じるボタン
      popovers.forEach((popover) => {
        const closeButton = popover.querySelector(".js-popoverClose");
        closeButton.addEventListener("click", () => {
          parentSlider.dataset.state = null;
          popover.ariaHidden = "true";
          document.body.style.overflow = null;
        });
      });
    });
  });
};