star back image
people4
電飾 電飾
moon
men
Slickスライダー ページネーションをプログレスバーにしたい

【Slick】スライダーのページネーションをプログレスバーにしたい

BLOG WEBログ
読了約:24分

スライダーのページネーションをプログレスバー風にしたい。
そういう案件はないでしょうか。

以下のような感じを再現したいです。

プログレスバー風にしたい

飾りですね。あまりみないレアな要件だと思います。

Slickスライダーって知ってますか?
bxSliderの次くらいに現れた古参のスライダーライブラリです。

Slickスライダー:公式
https://kenwheeler.github.io/slick/
今でもいろんなところで大活躍しているようです。

みんな大好きSlickスライダーだ!

今の流行りだと、SwiperとかSplideが新しく有名でしょうか。

誰かの役にたつ記事になることはなさそうですね。でも(>ω<。)づ

【共有】プログレスバー版のサンプルコード

サンプルソースを以下に共有します。

サンプルページ
https://astrowave.jp/amnesia_record/progress_bar_slick.php
今回、左に隙間があるタイプのループしないスライダーをご用意。

要件をまとめますと以下になります。

・Slickスライダーを使う。
・PREV/NEXTボタンを使い、オートで自動スライドしない。
・Dotのページネーションではない。
・どれくらいの量を進んだのかスライド枚数を表示させたい。
・バーを押してもスライドしない。(飾り)

検索してもなかなか見つからない。でもchatGPTにやりたいことを聞けば、1発でコード書いてくれます。

html

<link rel="stylesheet" href="./slick/slick.css">
<script src="./slick/slick_1-8-0.js"></script>

<section class="main">
  <p>●左に隙間があるループしないスライダー</p>
  <div class="slide-wrap">
    <ul class="product-slider1-1">
      <li>
        <div class="item">
          <img src="img/slide01.png" alt="">
          <p>slide01</p>
        </div>
      </li>
      <li>
        <div class="item">
          <img src="img/slide02.png" alt="">
          <p>slide02</p>
        </div>
      </li>
      <li>
        <div class="item">
          <img src="img/slide03.png" alt="">
          <p>slide03</p>
        </div>
      </li>
      <li>
        <div class="item">
          <img src="img/slide04.png" alt="">
          <p>slide04</p>
        </div>
      </li>
      <li>
        <div class="item">
          <img src="img/slide05.png" alt="">
          <p>slide05</p>
        </div>
      </li>
      <li>
        <div class="item">
          <img src="img/slide06.png" alt="">
          <p>slide06</p>
        </div>
      </li>
    </ul>
  </div>
</section>

公式よりダウンロードした「slick_1-8-0.js」「slick.css」を読み込ませてご利用ください。

jQueryの読み込ませも忘れずに。

css

.main {
  overflow: hidden;
}
.slide-wrap {
  margin: 30px 0 100px 20px;
}
.item {
  width: 315px;
  height: auto;
  padding-left: 0;
  padding-right: 15px;
  display: block;
  cursor:grab;
}
.item:active {
  cursor:grabbing;
}
.slick-slide img {
  border: none;
  max-width: 100%;
  height: auto;
}
.item p {
  margin: 1em 0em 0;
  color: #000;
  font-size: 12px;
  letter-spacing: 0.05em;
}
.slick-nav {
  position: relative;
  margin: 0 auto;
}
.slick-num {
  width: auto;
  margin: 0 auto 5px;
  font-size: 14px;
  letter-spacing: 0.06em;
  line-height: calc(27 / 14);
  text-align: center;
  color: #000;
}
.arrow_box {
  width: 100%;
  position: relative;
  top: 0;
}
.slick-slider {
  padding: 0 0 2em;
  margin: 0;
}
.slick-arrow {
  width: 50px;
  height: 50px;
  background: url("./img/icon_arrow.svg") no-repeat 0 0 / 100% auto;
  cursor: pointer;
  font-size: 2px;
  color: transparent;
  overflow: hidden;
  text-indent: 40px;
  border: none;
  position: absolute;
  z-index: 10;
  top: unset;
  bottom: unset;
}
.slick-arrow.slick-prev {
  left: 0;
  top: 0;
  transform: translateY(-50%);
  opacity: 1.0;
  transition: opacity .4s ease-out;
}
.slick-arrow.slick-next {
  right: 0;
  top: 0;
  transform: rotateY(180deg) translateY(-50%);
  opacity: 1.0;
  transition: opacity .4s ease-out;
}
.slick-arrow.slick-prev:hover,
.slick-arrow.slick-next:hover {
  opacity: 0.6;
}
.slick-arrow.slick-prev.slick-disabled,
.slick-arrow.slick-next.slick-disabled {
  opacity: 0.5;
  pointer-events: none;
  cursor: pointer;
}
.progress-container {
  width: calc(100% - 100px);
  height: 1px;
  background-color: #CECECE;
  position: relative;
	margin: 0 auto;
}
.progress-bar1-1 {
  width: 0;
  height: 100%;
  background-color: #000000;
  position: absolute;
  top: 0;
  left: 0;
  transition: width 0.5s ease;
}
@media screen and (max-width:767px) {
  .slide-wrap {
    width: auto;
    margin: 30px 0 50px 30px;
  }
  .slick-slider {
    padding: 0 0 1em;
  }
  .item {
    width: 225px;
    padding-right: 13px;
    cursor:grab;
  }
  .item:active {
    cursor:grabbing;
  }
  .item p {
    margin: 0.7em 0 0;
    font-size: 12px;
    letter-spacing: 0.06em;
  }
  .slick-nav, {
    width: auto;
    position: relative;
    right: calc(50% + -50%);
    bottom: 0;
    margin: 0 auto;
  }
  .slick-num {
    width: auto;
    margin: 0 auto 5px;
    font-size: 14px;
    letter-spacing: 0.06em;
    line-height: calc(27 / 14);
    text-align: center;
    color: #000;
  }
  .arrow_box {
    position: relative;
    top: 1px;
  }
  .progress-container {
    width: calc(100% - 100px);
    height: 1px;
    background-color: #A7A7A7;
    position: relative;
    margin: 0 auto;
  }
  .slick-arrow {
    width: 50px;
    height: 50px;
    background: url("./img/icon_arrow.svg") no-repeat 0 0 / 100% auto;
    cursor: pointer;
    font-size: 2px;
    color: transparent;
    overflow: hidden;
    text-indent: 40px;
    border: none;
    position: absolute;
    z-index: 10;
    top: unset;
    bottom: unset;
  }
  .slick-arrow.slick-prev {
    left: 0;
    top: 0;
    transform: translateY(-50%);
    opacity: 1.0;
    transition: opacity .4s ease-out;
  }
  .slick-arrow.slick-next {
    right: 0;
    top: 0;
    transform: rotateY(180deg) translateY(-50%);
    opacity: 1.0;
    transition: opacity .4s ease-out;
  }

  .progress-bar1-1 {
    width: 0;
    height: 100%;
    background-color: #000000;
    position: absolute;
    top: 0;
    left: 0;
    transition: width 0.5s ease;
  }
}

class=”slick-nav”というdivをscriptで出力させて、その中にボタンやプログレスバーをまとめて入れたいと考えています。

script(jQuery)

<script>
$(function () {
  // 初期化時にプログレスバーを更新
  $('.product-slider1-1').on('init', function(event, slick) {
    var totalSlides = slick.slideCount;
    var percentage = (1 / totalSlides) * 100; // 最初のスライドの進捗を反映
    $('.progress-bar1-1').css('width', percentage + '%');
  });

  // スライダーの初期化
  $(document).ready(function() {
    $('.product-slider1-1').each(function(index, element) {
      var $slider = $(element);
      var $parentSlideWrap = $slider.closest('.slide-wrap');
      var $arrowBox = $parentSlideWrap.find('.arrow_box'); // スライダーに対応する矢印のコンテナを指定

      // slick-nav をスライダーの外側に追加
      if ($parentSlideWrap.find('.slick-nav').length === 0) {
        var $slickNav = $(
          '<div class="slick-nav">' +
            '<div class="slick-num"><span class="now-count"></span> / <span class="all-count"></span></div>' +
            '<div class="arrow_box"></div>' +
            '<div class="progress-container">' +
              '<div class="progress-bar1-1"></div>' +
            '</div>' +
          '</div>'
        );
        $parentSlideWrap.append($slickNav); // スライダーの親要素に追加
      }
    
      var $slickNav = $parentSlideWrap.find('.slick-nav');
      var $slickNum = $slickNav.find('.slick-num');
      var $progressContainer = $slickNav.find('.progress-container');
      
      $slider.on("init", function (event, slick) {
        // カウントの初期化
        $slickNum.find(".now-count").text(slick.currentSlide + 1);
        $slickNum.find(".all-count").text(slick.slideCount);
      }).slick({
        arrows: true,
        appendArrows: $slickNav.find('.arrow_box'), // 矢印をslick-navのarrow_boxに配置
        prevArrow: '<div class="slide-arrow prev-arrow slick-prev"></div>',
        nextArrow: '<div class="slide-arrow next-arrow slick-next"></div>',
        dots: false,
        infinite: false,
        fade: false,
        slidesToShow: 1,
        slidesToScroll: 1,
        speed: 600, // 切り替わり中のスピード
        autoplaySpeed: 4000, // 静止中のスピード
        autoplay: false,
        variableWidth: true,
        responsive: [
          {
            breakpoint: 768,
            settings: {
              arrows: true
            }
          }
        ]
      })
      .on("beforeChange", function (event, slick, currentSlide, nextSlide) {
        // カウントを更新
        $slickNum.find(".now-count").text(nextSlide + 1);
      });

      // スライダーが初期化されたときのプログレスバー更新
      $slider.on('init', function(event, slick) {
        updateProgressBar(slick.currentSlide, slick.slideCount, $slider);
      });

      // スライドが変更されるたびのプログレスバー更新
      $slider.on('beforeChange', function(event, slick, currentSlide, nextSlide) {
        updateProgressBar(nextSlide, slick.slideCount, $slider);
      });
    });

    // プログレスバー更新関数
    function updateProgressBar(currentSlide, totalSlides, $slider) {
      var percentage = ((currentSlide + 1) / totalSlides) * 100;
      $slider.closest('.slide-wrap').find('.progress-bar1-1').css('width', percentage + '%');
    }
  });

});// End function --jquery
</script>

誰かの役にたつ記事になることを願って。

役に立つとか考えなくても、いいんじゃないですか。

記事内容が短いでしょうか。

参考サイト置き場

参考にさせていただきました。ありがとうございます。

Slickスライダー:公式
https://kenwheeler.github.io/slick/

オランダで生きていく
https://nldot.info/how-to-change-slick-slider-by-slicktogo-on-hover/

星間旅路のメロディ

「宇宙の静けさに包まれながら、漂流する過去の音楽を捜し求め、銀河の奥底でその旋律に耳を傾ける。」

「この電波はどこの星からきたのだろうか。」