Progress slick slider dots с видео и автовоспроизведением

Есть slick slider с autoplay и видео:

if ($('.slider').length) {
  $('.slider').each(function() {

    var $this = $(this);


    $this.on('init', function(event) {
      $(".video").each(function(i, e) {
        e.play();
      });
    });

    $this.slick({
      slidesToShow: 1,
      slidesToScroll: 1,
      dots: true,
      infinite: true,
      autoplay: true,
      autoplaySpeed: 3000
    });




    function reloadBGVid() {
      $(".video").each(function(i, e) {
        if (e.paused) e.play();
      });
    }

  });
}
.slider,
.item {
  height: 20rem;
}

.item img {
  max-width: 100%;
}

.slick-dots {
  display: flex;
  justify-content: center;
  list-style-type: none;
  padding: 0;
  margin: 0;
  font-size: 0;
  line-height: 0;
  position: absolute;
  bottom: 1rem;
  left: 4rem;
}

.slick-dots li {
  width: 1.75rem;
  height: 1.75rem;
  opacity: 1;
  background-color: transparent;
  border: 1px solid #000;
  padding: 0px;
  font-size: 0px;
  line-height: 0px;
  cursor: pointer;
  position: relative;
  margin: 0 5px;
  opacity: .8;
  -webkit-transition: all .2s ease-in-out;
  -o-transition: all .2s ease-in-out;
  transition: all .2s ease-in-out;
}

.slick-dots li button {
  font-size: 0px;
  line-height: 0px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 0px;
  padding: 0;
  margin: 0;
  border: none;
  background: red;
}

.slider .slick-dots li:hover,
.slider .slick-dots li.slick-active {
  background-color: #a08a7f;
}

.slider .slick-dots li.slick-active~li {
  background-size: 0% 0%;
}


/* .slider .slick-dots li.slick-active{
  -webkit-animation:right 3s ease-in-out forwards;
  -moz-animation:right 3s ease-in-out forwards;
  -o-animation:right 3s ease-in-out forwards;
  animation:right 3s ease-in-out forwards;
}

@keyframes right{
  0%{
    background-size:0% 100%;
  }

  100%{
    background-size:100% 100%;
  }
} */

.slider .slick-dots li.slick-active button {
  -webkit-animation: rightB 3s ease-in-out forwards;
  -moz-animation: rightB 3s ease-in-out forwards;
  -o-animation: rightB 3s ease-in-out forwards;
  animation: rightB 3s ease-in-out forwards;
}

@keyframes rightB {
  0% {
    width: 0%;
  }
  100% {
    width: 100%;
  }
}
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.css" integrity="sha256-UK1EiopXIL+KVhfbFa8xrmAWPeBjMVdvYMYkTAEv/HI=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.js" integrity="sha256-NXRS8qVcmZ3dOv3LziwznUHPegFhPZ1F/4inU7uC8h0=" crossorigin="anonymous"></script>

<div class="slider">
  <div class="item">
    <video class="video" muted loop preload>
        <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
        <source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg">
          
      </video>
  </div>
  <div class="item">
    <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQu4CgFeghuoip9xGUET9Ebm4SHUoEHb35dVx1gtVv_Vrfv1i-5&usqp=CAU" alt="">
  </div>
  <div class="item">
    <img src="https://i.stack.imgur.com/NoaWt.jpg" alt="">
  </div>
</div>

На dots переключении реализован прогресс.

Вопрос: Как реализовать автовоспроизведение slick slider с учетом видео (т.е. при переключении на слайд с видео - воспроизведение слайда не 3 с, а до конца видео) и прогрессом на dots ?


Ответы (1 шт):

Автор решения: Grundy

Похоже встроенного автоизменения времени автоплея нет, однако можно сэмулировать.

Для этого нужно:

  1. проверить, что на текущем слайде есть видео
  2. если его нет - выставить стандартный интервал 3 секунды
  3. если есть
    1. остановить автоплей
    2. получить длительность видео
    3. установить длительность анимации на точке
    4. запустить автоплей
    5. запустить видео

Для получения длительности видео можно воспользоваться свойством duration. Однако, оно может быть не заполнено, в этом случае можно подписаться на событие loadedmetadata и внутри обработчика уже использовать данное свойство.

Пример реализации:

function defaultAutoplay(slick) {
  slick.options.autoplaySpeed = 3 * 1000;
  slick.play();
}

function videoAutoplay(slick, index, videoDuration, inited) {
  slick.options.autoplaySpeed = videoDuration * 1000;
  slick.play();
  if (!inited) {
    slick.$dots.find(`li:nth-child(${index+1}) button`)
      .css('animation-duration', `${videoDuration}s`)
      .addClass('inited-video');
  }
}

function processVideo(slick, index, video, inited) {
  slick.pause();

  if (isFinite(video.duration)) {
    video.play();
    return videoAutoplay(slick, index, video.duration, inited);
  }

  video.addEventListener('loadedmetadata', function() {
    videoAutoplay(slick, index, video.duration, inited);
  });
  video.play();
}

if ($('.slider').length) {
  $('.slider').each(function() {

    var $this = $(this);
    $this.on('init', function(event, slick) {
      var video = slick.$slides[slick.currentSlide].querySelector('video');
      if (!video) {
        return defaultAutoplay(slick);
      }

      processVideo(slick, slick.currentSlide, video);

    });

    $this.on('beforeChange', function(e, slick, currentSlide, nextSlide) {
      var video = slick.$slides[nextSlide].querySelector('video');
      if (!video) {
        return defaultAutoplay(slick);
      }

      var inited = slick.$dots.find(`li:nth-child(${nextSlide+1}) button`)
        .hasClass('inited-video');
      processVideo(slick, nextSlide, video, inited);
    });

    $this.slick({
      slidesToShow: 1,
      slidesToScroll: 1,
      dots: true,
      infinite: true,
      autoplay: true,
      autoplaySpeed: 3000
    });
  });
}
.slider,
.item {
  height: 20rem;
}

.item img {
  max-width: 100%;
}

.slick-dots {
  display: flex;
  justify-content: center;
  list-style-type: none;
  padding: 0;
  margin: 0;
  font-size: 0;
  line-height: 0;
  position: absolute;
  bottom: 1rem;
  left: 4rem;
}

.slick-dots li {
  width: 1.75rem;
  height: 1.75rem;
  opacity: 1;
  background-color: transparent;
  border: 1px solid #000;
  padding: 0px;
  font-size: 0px;
  line-height: 0px;
  cursor: pointer;
  position: relative;
  margin: 0 5px;
  opacity: .8;
  -webkit-transition: all .2s ease-in-out;
  -o-transition: all .2s ease-in-out;
  transition: all .2s ease-in-out;
}

.slick-dots li button {
  font-size: 0px;
  line-height: 0px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 0px;
  padding: 0;
  margin: 0;
  border: none;
  background: red;
}

.slider .slick-dots li:hover,
.slider .slick-dots li.slick-active {
  background-color: #a08a7f;
}

.slider .slick-dots li.slick-active~li {
  background-size: 0% 0%;
}


/* .slider .slick-dots li.slick-active{
  -webkit-animation:right 3s ease-in-out forwards;
  -moz-animation:right 3s ease-in-out forwards;
  -o-animation:right 3s ease-in-out forwards;
  animation:right 3s ease-in-out forwards;
}

@keyframes right{
  0%{
    background-size:0% 100%;
  }

  100%{
    background-size:100% 100%;
  }
} */

.slider .slick-dots li.slick-active button {
  -webkit-animation: rightB 3s ease-in-out forwards;
  -moz-animation: rightB 3s ease-in-out forwards;
  -o-animation: rightB 3s ease-in-out forwards;
  animation: rightB 3s ease-in-out forwards;
}

@keyframes rightB {
  0% {
    width: 0%;
  }
  100% {
    width: 100%;
  }
}
<script src="https://code.jquery.com/jquery-3.0.0.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.min.css" integrity="sha256-UK1EiopXIL+KVhfbFa8xrmAWPeBjMVdvYMYkTAEv/HI=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.9.0/slick.js" crossorigin="anonymous"></script>

<div class="slider">
  <div class="item">
    <video class="video" muted preload>
        <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
        <source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg">
          
      </video>
  </div>
  <div class="item">
    <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQu4CgFeghuoip9xGUET9Ebm4SHUoEHb35dVx1gtVv_Vrfv1i-5&usqp=CAU" alt="">
  </div>
  <div class="item">
    <video class="video" muted preload>
        <source src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
        <source src="https://www.w3schools.com/html/mov_bbb.ogg" type="video/ogg">
          
      </video>
  </div>
  <div class="item">
    <img src="https://i.stack.imgur.com/NoaWt.jpg" alt="">
  </div>
</div>

→ Ссылка