each + setinterval +addClass [дубликат]

326
24 августа 2021, 12:50
На этот вопрос уже дан ответ здесь:
Как куда-нибудь передать функцию // почему событие вызывается сразу же? (1 ответ)
Закрыт 1 год назад.

Подскажите, как запустить бесконечный цикл добавления у убирания класса?

делаю свечки. каждые 2 секунды, свечка должна менять класс, а через 1 секунду - убирать его.

На текущий момент js такой -

$(function(){
var one = $('div.one'),
    two = $('div.two'),
    three = $('div.three'),
    four = $('div.four'),
    five = $('div.five'),
    six = $('div.six'),
    seven = $('div.seven');
    $('button.start').on('click', function () {
        $('div.circle').each(function () {
            setInterval($(this).addClass('active'), 1000);
        });
    });});

Подскажите что сделать, чтобы было как заявлено выше?

Answer 1

Кажется так)

let candle = document.querySelectorAll('.candle'); 
let on = false; 
let interval; // Будем хранить здесь интервал, чтобы прервать, если захочется. 
document.getElementById('on').addEventListener('click', function(){ 
  on = !on; // Воскл. знак переворачивает значение. false станет true, а true → false 
  this.textContent = on ? "OFF" : "ON"; 
  if( on ){ // Если включили 
    let curr = 0; // Индекс текущей свечки 
    interval = setInterval(function(){ 
      candle[curr].classList.add('active'); 
      setTimeout(function(){ 
        candle[curr].classList.remove('active'); 
        // Увелививаем индекс на единицу, если есть куда расти. Иначе - сбрасываем на 0 
        curr = (curr == candle.length - 1) ? 0 : curr + 1; 
      }, 1000); // Через секунду отключаем 
    }, 2000); // Раз в 2 секунды переключаем 
  } else { // Если on оказался false 
    clearInterval(interval); 
    candle.forEach(function(e){ 
      e.classList.remove('active'); 
    }); 
  } 
});
/* Ненужные декорации; В реальной жизни не надо так делать - нагружает CPU */ 
body { 
  background-color: #22262b; 
} 
.candle { 
  display: inline-block; 
  position: relative; 
  height: 100px; 
  width: 30px; 
  background-image: linear-gradient(to right, #cca, #fff, #997); 
  margin: 50px 10px; 
} 
.candle::after { 
  content: ""; 
  position: absolute; 
  width: 30px; 
  height: 5px; 
  border-bottom: 1px solid black; 
  border-radius: 50%; 
  bottom: -2px; 
  background-image: linear-gradient(to right, #cca, #fff, #997); 
} 
.candle.active::before { 
  content: ""; 
  position: absolute; 
  width: 12px; 
  height: 37px; 
  margin: auto; 
  left: 0; right: 0; 
  top: -37px; 
  background-image: radial-gradient(#ff0 20%, #f36700 70%, #990); 
  border-radius: 50%; 
  animation: 0.2s linear light infinite; 
} 
 
@keyframes light { 
  0% { transform: rotate(3deg) translateX(1px) scale(1,1.1) } 
 50% { transform: rotate(-3deg) translateX(-1px) scale(1.1,1) } 
100% { transform: rotate(3deg) translateX(1px) } 
} 
 
#on { 
  font-size: 30px; 
  position: absolute; 
  top: 5px; right: 5px; 
}
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
 
<button id="on">ON</button>

Перевод на jQuery, который здесь не особо сокращает код:

let $candle = $('.candle'); 
let on = false; 
let interval = null; 
$('#on').on('click', function(){ 
  on = !on; 
  $(this).text( on ? "OFF" : "ON" ); 
  if( on ){ 
    let curr = 0; 
    interval = setInterval(function(){ 
      $candle.eq(curr).addClass('active'); 
      setTimeout(function(){ 
        $candle.eq(curr).removeClass('active'); 
        curr = curr == $candle.length - 1 ? 0 : curr + 1; 
      }, 1000); 
    }, 2000); 
  } else { 
    clearInterval(interval); 
    $candle.each(function(){ 
      $(this).removeClass('active'); 
    }); 
  } 
});
body { 
  background-color: #22262b; 
} 
.candle { 
  display: inline-block; 
  position: relative; 
  height: 100px; 
  width: 30px; 
  background-image: linear-gradient(to right, #cca, #fff, #997); 
  margin: 50px 10px; 
} 
.candle::after { 
  content: ""; 
  position: absolute; 
  width: 30px; 
  height: 5px; 
  border-bottom: 1px solid black; 
  border-radius: 50%; 
  bottom: -2px; 
  background-image: linear-gradient(to right, #cca, #fff, #997); 
} 
.candle.active::before { 
  content: ""; 
  position: absolute; 
  width: 12px; 
  height: 37px; 
  margin: auto; 
  left: 0; right: 0; 
  top: -37px; 
  background-image: radial-gradient(#ff0 20%, #f36700 70%, #990); 
  border-radius: 50%; 
  animation: 0.2s linear light infinite; 
} 
 
@keyframes light { 
  0% { transform: rotate(3deg) translateX(1px) scale(1,1.1) } 
 50% { transform: rotate(-3deg) translateX(-1px) scale(1.1,1) } 
100% { transform: rotate(3deg) translateX(1px) } 
} 
 
#on { 
  font-size: 30px; 
  position: absolute; 
  top: 5px; right: 5px; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
<div class="candle"></div> 
 
<button id="on">ON</button>

P.s. можно было сделать через один интервал раз в секунду, но пришлось бы добавить доп проверки - включать или выключать.

READ ALSO
как передать переменной значение span class

как передать переменной значение span class

Пишу скрипт, вот кусок кода страницы

158
JSON Сериализация Dictionary

JSON Сериализация Dictionary

Помогите плиз, как можно такое заджейсонитьИспользую юнити

189
Как собрать выражение для конкатенации свойств произвольного класса?

Как собрать выражение для конкатенации свойств произвольного класса?

Хочу с помощью деревьев выражений LINQ сгенерировать делегат, который будет делать конкатенацию всех строковых свойств произвольного типа:

131
Как привести к generic типу?

Как привести к generic типу?

нельзя просто взять и привестиTType может быть int, string, etc

97