Что не так с моим слайдером?

98
11 марта 2021, 09:10

Немного освоившись в JS'e и jQuery, попробовал написать свой слайдер.

$(document).ready(function(){ 
    $(".gallery-dot:nth-child(1)").css("background-color", "#1a1a1a"); 
    $(window).on("resize load",function(){ 
        if ($(window).width() <= 767){ 
            $(".gallery-current-image").css("object-fit","contain"); 
        } else { 
            $(".gallery-current-image").css("object-fit","cover"); 
        } 
    }) 
 
    var images = []; 
    var i = 0; 
    for (var image of $(".gallery-item-image")){ 
        images.push($(image).attr("src")); 
    } 
 
    setInterval(function(){return i++}, 2000); 
 
    setInterval(function(){ 
        if (i == images.length){ 
            i = 0; 
            var prev_dot = $(".gallery-dot")[images.length-1]; 
        } else { 
            var prev_dot = $(".gallery-dot")[i-1]; 
        } 
        var current_dot = $(".gallery-dot")[i]; 
         
        $(".gallery-current-image").attr("src",images[i]); 
        $(current_dot).css("background-color", "#1a1a1a"); 
        $(prev_dot).css("background-color", "#a6a6a6"); 
    }, 2000); 
 
    $(".gallery-dot").on("click",function(){ 
        let clicked_dot_index = $(this).index(); 
        let old_dot = $(".gallery-dot")[i]; 
        let new_dot = $(".gallery-dot")[clicked_dot_index]; 
 
        $(old_dot).css("background-color", "#a6a6a6"); 
        $(new_dot).css("background-color", "#1a1a1a"); 
        $(".gallery-current-image").attr("src",images[clicked_dot_index]); 
        i = clicked_dot_index; 
    }); 
});
.gallery-all-images,.low-res{ 
    display: none; 
} 
 
.gallery-wrapper{ 
    width: 100%; 
    height: 500px; 
} 
 
.gallery-img-wrapper{ 
    width: 100%; 
    height: 100%; 
    position: relative; 
} 
 
.gallery-current-image{ 
    width: 100%; 
    height: 100%; 
    object-fit: cover; 
    background-color: black; 
} 
 
.gallery-dots{ 
    width: 100%; 
    height: 40px; 
    text-align: center; 
    position: absolute; 
    bottom: 0; 
    background-color: rgba(89, 89, 89, 0.65); 
    border-top: 2px solid #fff; 
    border-radius: 100px 100px 0 0; 
} 
 
.gallery-dot{ 
    width: 1rem; 
    height: 35%; 
    background-color: #a6a6a6; 
    border-radius: 100%; 
    display: inline-block; 
    margin-top: 0.70rem; 
    cursor: pointer; 
}
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <meta http-equiv="X-UA-Compatible" content="ie=edge"> 
    <link rel="stylesheet" href="static/static/main.css"> 
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> 
    <title>Document</title> 
</head> 
<body> 
 
    <div class="gallery"> 
        <div class="container"> 
            <div class="row"> 
                <div class="col-md-12"> 
                    <div class="gallery-wrapper"> 
                        <div class="gallery-img-wrapper"> 
                        <img src="https://belgium-guide.ru/wp-content/uploads/2018/10/foto-hallerbosa-17.jpg" alt="" class="gallery-current-image"> 
                            <div class="gallery-dots"> 
                                <div class="gallery-dot"></div> 
                                <div class="gallery-dot"></div> 
                                <div class="gallery-dot"></div> 
                                <div class="gallery-dot"></div> 
                            </div> 
                        </div> 
                        <div class="gallery-all-images"> 
                            <img class="gallery-item-image" src="https://belgium-guide.ru/wp-content/uploads/2018/10/foto-hallerbosa-17.jpg" alt=""> 
                            <img class="gallery-item-image" src="https://tumentoday.ru/media/gallery_images/bialowiezaforestctomaszwilk0.jpg" alt=""> 
                            <img class="gallery-item-image" src="https://avatars.mds.yandex.net/get-pdb/25978/ee1780c5-7223-4d25-8ed3-6c16c2c2a1fa/orig" alt=""> 
                            <img class="gallery-item-image" src="https://avatars.mds.yandex.net/get-pdb/25978/3b8dd671-b906-4216-a8f7-60b3ffdb5a16/orig" alt=""> 
                        </div> 
                    </div> 
                </div> 
            </div> 
        </div> 
    </div> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<script src="static/static/scripts.js"></script> 
</body> 
</html>

Я хочу чтобы после клика на одну из точек, слайдер стоял на месте еще 2 секунды. Сейчас же, если подождать секунду-полторы, то таймер продолжит идти в своим чередом. Я пытался сбросить таймер и поставить по новой,но, слайдер почему-то ускорялся в 2 раза после каждого сброса интервала.

Answer 1

Самый простой вариант - завести флаг, который пропускает одно переключение:

$(document).ready(function() { 
  $(".gallery-dot:nth-child(1)").css("background-color", "#1a1a1a"); 
  $(window).on("resize load", function() { 
    if ($(window).width() <= 767) { 
      $(".gallery-current-image").css("object-fit", "contain"); 
    } else { 
      $(".gallery-current-image").css("object-fit", "cover"); 
    } 
  }) 
 
  var images = []; 
  var i = 0; 
  var skipOneChange; 
   
  for (var image of $(".gallery-item-image")) { 
    images.push($(image).attr("src")); 
  } 
 
  setInterval(function() { 
   
    if (skipOneChange) {       
      skipOneChange = false; 
      return; 
    } 
   
    i++ 
 
    if (i == images.length) { 
      i = 0; 
      var prev_dot = $(".gallery-dot")[images.length - 1]; 
    } else { 
      var prev_dot = $(".gallery-dot")[i - 1]; 
    } 
    var current_dot = $(".gallery-dot")[i]; 
 
    $(".gallery-current-image").attr("src", images[i]); 
    $(current_dot).css("background-color", "#1a1a1a"); 
    $(prev_dot).css("background-color", "#a6a6a6"); 
     
  }, 2000); 
 
  $(".gallery-dot").on("click", function() { 
    let clicked_dot_index = $(this).index(); 
    let old_dot = $(".gallery-dot")[i]; 
    let new_dot = $(".gallery-dot")[clicked_dot_index]; 
 
    $(old_dot).css("background-color", "#a6a6a6"); 
    $(new_dot).css("background-color", "#1a1a1a"); 
    $(".gallery-current-image").attr("src", images[clicked_dot_index]); 
    i = clicked_dot_index; 
     
    skipOneChange = true; /// 
  }); 
});
.gallery-all-images, 
.low-res { 
  display: none; 
} 
 
.gallery-wrapper { 
  width: 100%; 
  height: 500px; 
} 
 
.gallery-img-wrapper { 
  width: 100%; 
  height: 100%; 
  position: relative; 
} 
 
.gallery-current-image { 
  width: 100%; 
  height: 100%; 
  object-fit: cover; 
  background-color: black; 
} 
 
.gallery-dots { 
  width: 100%; 
  height: 40px; 
  text-align: center; 
  position: absolute; 
  bottom: 0; 
  background-color: rgba(89, 89, 89, 0.65); 
  border-top: 2px solid #fff; 
  border-radius: 100px 100px 0 0; 
} 
 
.gallery-dot { 
  width: 1rem; 
  height: 35%; 
  background-color: #a6a6a6; 
  border-radius: 100%; 
  display: inline-block; 
  margin-top: 0.70rem; 
  cursor: pointer; 
}
<div class="gallery"> 
  <div class="container"> 
    <div class="row"> 
      <div class="col-md-12"> 
        <div class="gallery-wrapper"> 
          <div class="gallery-img-wrapper"> 
            <img src="https://belgium-guide.ru/wp-content/uploads/2018/10/foto-hallerbosa-17.jpg" alt="" class="gallery-current-image"> 
            <div class="gallery-dots"> 
              <div class="gallery-dot"></div> 
              <div class="gallery-dot"></div> 
              <div class="gallery-dot"></div> 
              <div class="gallery-dot"></div> 
            </div> 
          </div> 
          <div class="gallery-all-images"> 
            <img class="gallery-item-image" src="https://belgium-guide.ru/wp-content/uploads/2018/10/foto-hallerbosa-17.jpg" alt=""> 
            <img class="gallery-item-image" src="https://tumentoday.ru/media/gallery_images/bialowiezaforestctomaszwilk0.jpg" alt=""> 
            <img class="gallery-item-image" src="https://avatars.mds.yandex.net/get-pdb/25978/ee1780c5-7223-4d25-8ed3-6c16c2c2a1fa/orig" alt=""> 
            <img class="gallery-item-image" src="https://avatars.mds.yandex.net/get-pdb/25978/3b8dd671-b906-4216-a8f7-60b3ffdb5a16/orig" alt=""> 
          </div> 
        </div> 
      </div> 
    </div> 
  </div> 
</div> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Вариант посложнее, с таймаутами вместо таймера.

по клику удаляется старый таймаут и навешивается новый, таким образом отсчет идет непосредственно от момента клика

$(".gallery-dot:nth-child(1)").css("background-color", "#1a1a1a"); 
 
$(window).on("resize load", function() { 
    $(".gallery-current-image").css("object-fit",  
      $(window).width() <= 767 ? "contain" : "cover"); 
}) 
 
var images = []; 
var i = 0; 
 
for (var image of $(".gallery-item-image")) { 
  images.push($(image).attr("src")); 
} 
 
var to = setTimeout(tick, 2000); 
 
$(".gallery-dot").on("click", function() { 
  render(i = $(this).index()); 
  clearTimeout(to); 
  to = setTimeout(tick, 2000); 
}); 
 
function tick() { 
  render(i = i === images.length - 1 ? 0 : i + 1); 
  to = setTimeout(tick, 2000); 
} 
 
function render(index) { 
  $(".gallery-current-image").attr("src", images[index]); 
  $(".gallery-dot").css("background-color", "#a6a6a6") 
         .eq(index).css("background-color", "#1a1a1a"); 
}
.gallery-all-images, 
.low-res { 
  display: none; 
} 
 
.gallery-wrapper { 
  width: 100%; 
  height: 500px; 
} 
 
.gallery-img-wrapper { 
  width: 100%; 
  height: 100%; 
  position: relative; 
} 
 
.gallery-current-image { 
  width: 100%; 
  height: 100%; 
  object-fit: cover; 
  background-color: black; 
} 
 
.gallery-dots { 
  width: 100%; 
  height: 40px; 
  text-align: center; 
  position: absolute; 
  bottom: 0; 
  background-color: rgba(89, 89, 89, 0.65); 
  border-top: 2px solid #fff; 
  border-radius: 100px 100px 0 0; 
} 
 
.gallery-dot { 
  width: 1rem; 
  height: 35%; 
  background-color: #a6a6a6; 
  border-radius: 100%; 
  display: inline-block; 
  margin-top: 0.70rem; 
  cursor: pointer; 
}
<div class="gallery"> 
  <div class="container"> 
    <div class="row"> 
      <div class="col-md-12"> 
        <div class="gallery-wrapper"> 
          <div class="gallery-img-wrapper"> 
            <img src="https://belgium-guide.ru/wp-content/uploads/2018/10/foto-hallerbosa-17.jpg" alt="" class="gallery-current-image"> 
            <div class="gallery-dots"> 
              <div class="gallery-dot"></div> 
              <div class="gallery-dot"></div> 
              <div class="gallery-dot"></div> 
              <div class="gallery-dot"></div> 
            </div> 
          </div> 
          <div class="gallery-all-images"> 
            <img class="gallery-item-image" src="https://belgium-guide.ru/wp-content/uploads/2018/10/foto-hallerbosa-17.jpg" alt=""> 
            <img class="gallery-item-image" src="https://tumentoday.ru/media/gallery_images/bialowiezaforestctomaszwilk0.jpg" alt=""> 
            <img class="gallery-item-image" src="https://avatars.mds.yandex.net/get-pdb/25978/ee1780c5-7223-4d25-8ed3-6c16c2c2a1fa/orig" alt=""> 
            <img class="gallery-item-image" src="https://avatars.mds.yandex.net/get-pdb/25978/3b8dd671-b906-4216-a8f7-60b3ffdb5a16/orig" alt=""> 
          </div> 
        </div> 
      </div> 
    </div> 
  </div> 
</div> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

READ ALSO
Определить является ли значение цветом

Определить является ли значение цветом

Как реализовать проверку значения на цвет HEX, RGB или RGBA системы

91
Физика в canvas. Программа плохо понимает столкновения объектов

Физика в canvas. Программа плохо понимает столкновения объектов

Согласно рекомендациям @Stranger in the Q, я сделал проверку на столкновения отдельным таймером, но так еще хужеМожет есть еще способы получше проверять...

110
Получить width экрана css

Получить width экрана css

Мне необходимо настроить @viewport в CSS вот таким образом:

117