質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.22%

スリックスライダーのdotsをプログレスバーにしたい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 268

UKYO9311

score 27

前提・実現したいこと

スリックスライダーを使ってTOPページを実装しているのですが、dots部分をプログレスバーに変更したいです。
イメージはこんな感じです。

イメージ説明

01のバーが100%になったら画像が切り替わり、02のバーがスタートします。

現在はこのような感じになっていて、スライダーに合わせて色も変わります。
イメージ説明

このサイトを参考に作っています。
https://peaceday.jp/2019/

発生している問題・エラーメッセージ

スライダーは正常に動いていて、エラーは出ていません。

該当のソースコード

<div class="slider">
   <div>

     中略

     <img alt="Alt" src="images/top_kv1-1.jpg" />
     </div>
     <div>

     中略

     <img alt="Alt" src="images/top_kv1-1.jpg" />
     </div>
     <div>

     中略

     <img alt="Alt" src="images/top_kv1-1.jpg" />
     </div>
     <div>

     中略

     <img alt="Alt" src="images/top_kv1-1.jpg" />
   </div>
</div>
/* Slider */
.slider-wrapper{
    position: relative;
    overflow: hidden;
    width: 100%;

  }


  .slick-list {
    position: relative;
    overflow: hidden;
    display: block;
    margin: 0;
    padding: 0;
  }

  .slick-list:focus {
    outline: none;
  }

  .slick-list.dragging {
    cursor: pointer;
    cursor: hand;
  }

  .slick-slider .slick-list,
  .slick-track,
  .slick-slide,
  .slick-slide img {
    height: 100vh;
    object-fit: cover;
  }

  .slick-track {
    position: relative;
    left: 0;
    top: 0;
    display: block;
    zoom: 1;
  }

  .slick-track:before,
  .slick-track:after {
    content: "";
    display: table;
  }

  .slick-track:after {
    clear: both;
  }

  .slick-loading .slick-track {
    visibility: hidden;
  }

  .slick-slide {
    float: left;
    height: 100%;
    min-height: 1px;
    display: none;
  }

  .slick-slide img {
    width: 100%;
    height: 100vh;
    margin-top: 82px;
  }

  .slick-slide.dragging img {
    pointer-events: none;
    width: 100%;
    height: 100vh;
  }

  .slick-initialized .slick-slide {
    display: block;
  }

  .slick-loading .slick-slide {
    visibility: hidden;
  }

  .slick-vertical .slick-slide {
    display: block;
    height: auto;
    border: 1px solid transparent;
  }

  .slick-slide > .slick-slider-img {
    position: relative;
    display: block;
    width: 100%;
    height: 100vh;
  }

  .slick-slide .image {
    /*height: 180px;*/
    height: 100vh;
    width: 100%;
    margin: 0 auto;
  }

  .slick-slide img {
    display: block;
    width: 100%;
    height: 100vh;
  }

  .slick-slide img.slick-loading {
    display: none;
  }


  .slick-prev{
    width: 65px;
    border: none;
    border-radius: none;
    position: absolute;
    top: 50%;
    transform: translateY(-20%);
    left: 115px;
    padding: 0.25em 0.5em;
    z-index: 400;
  }

  .slick-next{
    width: 65px;
    border: none;
    border-radius: none;
    position: absolute;
    top: 50%;
    transform: translateY(-20%);
    right: 115px;
    padding: 0.25em 0.5em;
    z-index: 400;
  }








@media screen and (max-width: 767px) {

    .slick-slide img{
        margin-top: 62px;
    }

    .slick-next{
        display: none!important;
        }

    .slick-prev{
        display: none!important;
        }
    }








  .progress-bars {
      position: absolute;
      top: 80%;
      left: 0;
      right: 0;
      overflow: hidden;
      width: 100%;
      max-width: 1200px;
      margin: 0 auto;
      display: flex;
      padding-bottom: 10px;
  }

  .progress-bar-box {
      height: 2px;
      width: 25%;
      margin: 10px;
      font-size: 1.2rem;
      font-weight: bold;

      span{
        display: block!important;
        margin-top: 10px;
      }

  }

  .progress-bar-box:nth-child(even) {
    background-color: #aaa;
}

.progress-bar-box:nth-child(odd) {
    background-color: #aaa;
}


  .bar {
      height: 100%;
      width: 0px;
  }
//
//   Slider   ------------------------------
//


$(document).ready(function() {

  const barColors = ['#fff', '#fff', '#fff','#fff'];

  $.fn.startBar = function(index) {
      this
          .eq(index)
          .css({ backgroundColor: barColors[index]})
          .animate({ width: '100%' }, 3400 );
  }

  $('.slider').slick({
      autoplay: true,
      arrows: true,
      dots: false,
      speed: 800,
      autoplaySpeed: 3000,
      prevArrow: '<img src="images/slick-prev.svg" class="slide-arrow slick-prev">',
      nextArrow: '<img src="images/slick-next.svg" class="slide-arrow slick-next">',
      adaptiveHeight: true
  }).on('afterChange', function(event, slick, currentSlide) {
    if (currentSlide === 0)
        $('.bar').startBar(currentSlide);
        $('.bar').css({width: 0}).startBar(currentSlide);
        $('.bar').css({width: 0});
  });

  $('.bar').startBar(0);

});

補足

イメージ説明

二週目からこのようになってしまいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/07/24 14:38

    https://teratail.com/questions/201906
    ↑この質問とはどう違うのでしょうか?
    同じ質問なのであれば、質問は編集できますし編集したりすることで「アクティブ」タブにあがってくるので新しい質問を立てる必要はないと思います

    キャンセル

  • UKYO9311

    2019/07/24 14:55

    ご指摘ありがとうございます。。。
    おっしゃる通りだと思います。もう前の質問は古くなってしまったと思い新しく質問を立ててしまいました。。。

    キャンセル

  • m.ts10806

    2019/07/24 14:56

    どちらか質問の削除依頼を出しておくと良いです。

    キャンセル

  • UKYO9311

    2019/07/24 15:02

    ありがとうございます!!
    今、前回の質問の削除依頼を出しました。

    キャンセル

回答 1

checkベストアンサー

+3

こんにちは

slick の設定パラメータの中にある、以下を使うとできるのではと思います。

afterChange
Arguments: slick, currentSlide
Fires after slide change

試作してみました。作成したのは、以下の4点

  • index.html
  • main.js
  • style.css
  • extra.css

です。それぞれのソースコードを以下に挙げます。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Q202267</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
    <script type="text/javascript" src="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>
    <script src="main.js"></script>
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/>
    <link rel="stylesheet" type="text/css" href="style.css"/>
    <link rel="stylesheet" type="text/css" href="extra.css"/>
</head>
<body>

<div class="container">
    <div class="slider">
        <div>
            <img alt="Alt" src="https://dummyimage.com/600x400/0009ff/fff&text=1" />
        </div>
        <div>
            <img alt="Alt" src="https://dummyimage.com/600x400/09992d/fff&text=2" />
        </div>
        <div>
            <img alt="Alt" src="https://dummyimage.com/600x400/0009ff/fff&text=3" />
        </div>
        <div>
            <img alt="Alt" src="https://dummyimage.com/600x400/09992d/fff&text=4" />
        </div>
    </div>

    <div class="progress-bars">
        <div class="progress-bar-box"><div class="bar"></div></div>
        <div class="progress-bar-box"><div class="bar"></div></div>
        <div class="progress-bar-box"><div class="bar"></div></div>
        <div class="progress-bar-box"><div class="bar"></div></div>
    </div>
</div>


</body>
</html>

main.js

以下のように、 afterChange イベントに対するコールバックを設定して、その中でプログレスバーの塗りつぶしアニメーションを開始させています。

$(document).ready(function() {

    const barColors = ['#f00', '#ff0', '#f00','#ff0'];

    $.fn.startBar = function(index) {
       this
         .eq(index)
         .css({ backgroundColor: barColors[index]})
         .animate({ width: '100%' }, 3000 );
    }

    $('.slider').slick({
        autoplay: true,
        arrows: true,
        dots: false,
        speed: 1200,
        autoplaySpeed: 3000,
        prevArrow: '<img src="https://dummyimage.com/100x100/fff/000&text=Prev" class="slide-arrow slick-prev">',
        nextArrow: '<img src="https://dummyimage.com/100x100/fff/000&text=Next" class="slide-arrow slick-next">',
        adaptiveHeight: true
    }).on('afterChange', function(event, slick, currentSlide) {
        if (currentSlide === 0)
            $('.bar').css({width: 0});
        $('.bar').startBar(currentSlide);
    });

    $('.bar').startBar(0);
});

style.css

ご質問にあるCSSをコピペして作成したCSSファイルです。

extra.css

動作確認用に新たに追加したスタイルです。

.container {
    position: relative;
}

.progress-bars {
    position: absolute;
    top: 90%;
    overflow: hidden;
    width: 100%;
    margin-top: 20px;
    margin-bottom: 20px;
}

.progress-bar-box {
    float: left;
    height: 32px;
    width: 25%;
}

.bar {
    height: 100%;
    width: 0px;
}

img {
    margin-top: 4px !important;
}

以下の動画は、上記の index.html をブラウザで表示させたところです。

以上、参考になれば幸いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/26 20:41

    どういたしまして。

    > ほぼデザイン通りに再現することができました。

    との件、よかったです 👏

    > スライダーが時々止まって動かなくなってしまう時があるのですが、読み込みの問題でしょうか??

    悩ましいですね。「こういう条件があると、止まってしまう」というような、不具合のおこる前提となる状況をどうにか少しでも特定して、また別の質問として投稿されるとよいかもしれません。

    > 言葉ではわかりにくいため上に現在のコードと画像を貼ります。

    現在のコードと画像を拝見しまして、ここが怪しいのでは?と思う点として、私が動作確認したコードとの相違点を以下に2つ挙げます。

    (1) バーを animate するときに与える時間

    現在のコードのほうを見ると

      .animate({ width: '100%' }, 3400 );

    となっていて、 3400 ミリ秒を指定していますが、私の作成したコードでは 3000ミリ秒 にしており、これは slick に与える設定の

      autoplaySpeed: 3000,

    に合わせる意図でした。この autoplaySpeed のミリ秒数と、animate の第二引数で与えるミリ秒数とが違っていると、なんとなく、だんだんズレていくのでは?と思ったりします。(UKYO9311さんの検証によって、何らか妥当な理由により、400ミリ秒差をつけているのであれば問題ありません。)


    (2) on afterChange に与えるコールバック

    ご質問にある、現在のコードでは

    .on('afterChange', function(event, slick, currentSlide) {
    if (currentSlide === 0)
    $('.bar').startBar(currentSlide);
    $('.bar').css({width: 0}).startBar(currentSlide);
    $('.bar').css({width: 0});
    });

    となっていますが、私の修正後のものは

    https://github.com/jun68ykt/q202267/blob/master/main.js#L21-L23

    にあるとおり、

    .on('afterChange', function(event, slick, currentSlide) {
    $('.bar').css({width: 0}).startBar(currentSlide);
    });

    というものでした。

    以上です。

    私の回答の要点は以下の二つです。

    ・afterChange にコールバックを設定すれば、スライドの入れ替わりが完了したことを契機に何かを実行できる。

    ・上記の「何かを実行」として、 autoplaySpeed に設定した時間と同じ時間でアニメーションを開始すれば、スライドの動きとそのアニメーションを連動させることができる。

    さらにこれらに加えて、

    ・ afterChange とは逆に、スライドが動き始めるイベントも beforeChange として受け取れるので、これらを組み合わせれば、様々な表現が可能と思います。

    良いものが出来るといいですね。Good luck をお祈り申し上げます。

    キャンセル

  • 2019/07/27 17:36

    何度もご丁寧なご回答、本当に感謝しかありません( ; ; )
    修正してみたところ正常に動作しました!!途中で止まってしまったりしていたのもこの記述ミスだったみたいです。。。たくさん勉強もさせてもらいました!

    本当にありがとうございました!!!(>_<)

    キャンセル

  • 2019/07/27 22:31

    解決したようですね。よかったです 👍

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる