Как реализовать поочередную подсветку блоков javascript

Есть html код блока с контентом состоящим из других блоков, каждый блок имеет свой айдишник.

        <div class="collect-bonus-right">
            <div class="bebra"><p class="something">Steps to start traiding</p></div>
            <div class="collect-bonus-item" id  = "one">
                <div class="circle">01</div>
                <p class="collect-bonus-item-text">Download platfrom</p>
            </div>
            <div class="collect-bonus-item" id = "two">
                <div class="circle">02</div>
                <p class="collect-bonus-item-text">Create an account</p>
            </div>
            <div class="collect-bonus-item" id = "three">
                <div class="circle">03</div>
                <p class="collect-bonus-item-text">Select the crypto</p>
            </div>
            <div class="collect-bonus-item" id = "four">
                <div class="circle">04</div>
                <p class="collect-bonus-item-text">Start traiding</p>
            </div>
        </div>

Необходимо реализовать поочередную подсветку этих самых блоков через javascript что я собственно и попытался сделать.

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

let one = document.querySelector("#one");
  two = document.querySelector("#two");
  three = document.querySelector("#three");
  four = document.querySelector("#four")

let spotlightElements = [one, two, three, four];


async function spotlight(){
    for (let i = 0; i < spotlightElements.length; i++) {
       const element = spotlightElements[i];
    
       element.style.cssText = "box-shadow: 0px 0px 100px rgba(239, 68, 59, 0.4);";
       await sleep(i * 1000);
       element.style.cssText = "box-shadow: 0;";
    }
 }

проблема в том что код отрабатывает один раз, а мне необходимо чтобы код крутился постоянно и не прерывался. При помещении его в конструкцию setinterval код ведет себя не корректно и багано.

Заранее спасибо за ответ!


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

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

У вас ошибка в синтаксисе, поэтому отрабатывал только один элемент. Попробуйте так реализовать вечный цикл

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const one = document.querySelector("#one");
const two = document.querySelector("#two");
const three = document.querySelector("#three");
const four = document.querySelector("#four")

const spotlightElements = [one, two, three, four];

async function spotlightDo() {
  setTimeout(async () => {
    await spotlight();
  }, 1000)
}

async function spotlight(){
  for (let i = 0; i < spotlightElements.length; i++) {
    const element = spotlightElements[i];

    element.style.cssText = "box-shadow: 0px 0px 100px rgba(239, 68, 59, 0.4);";
    await sleep(i * 1000);
    element.style.cssText = "box-shadow: 0;";
  }
  spotlightDo();
}

spotlightDo();
→ Ссылка
Автор решения: IvaMuxa

предлагаю всё упростить и сделать функцию, которая перебирает элементы, ищет выделенный, снимает выделение с него и ставит выделение на следующий элемент. Запускаем функцию через setInterval на мой взгляд такой алгоритм более читабельный

let one = document.querySelector("#one");
two = document.querySelector("#two");
three = document.querySelector("#three");
four = document.querySelector("#four")

let spotlightElements = [one, two, three, four];


function spotlight() {
  for (let i = 0; i < spotlightElements.length; i++) {
    const element = spotlightElements[i];
    //ищем на каком элементе выделение
    if (element.classList.contains("shadowy")) {
      element.classList.toggle("shadowy");
      // снимаем с него и затем устанавливаем на следующий
      spotlightElements[(i + 1) % spotlightElements.length].classList.toggle("shadowy");
      return; //завершаем функцию дело сделано
    }
  }
}

setInterval(spotlight, 1000);
.shadowy {
  box-shadow: 0px 0px 100px rgba(239, 68, 59, 0.4);
}
<div class="collect-bonus-right">
  <div class="bebra">
    <p class="something">Steps to start traiding</p>
  </div>
  <div class="collect-bonus-item shadowy" id="one">
    <div class="circle">01</div>
    <p class="collect-bonus-item-text">Download platfrom</p>
  </div>
  <div class="collect-bonus-item" id="two">
    <div class="circle">02</div>
    <p class="collect-bonus-item-text">Create an account</p>
  </div>
  <div class="collect-bonus-item" id="three">
    <div class="circle">03</div>
    <p class="collect-bonus-item-text">Select the crypto</p>
  </div>
  <div class="collect-bonus-item" id="four">
    <div class="circle">04</div>
    <p class="collect-bonus-item-text">Start traiding</p>
  </div>
</div>

→ Ссылка
Автор решения: De.Minov

Вариант на CSS

.collect-bonus-item {
  animation: Active 4s steps(1) infinite;
}

.collect-bonus-item:nth-child(2) {animation-delay: 0s;}
.collect-bonus-item:nth-child(3) {animation-delay: 1s;}
.collect-bonus-item:nth-child(4) {animation-delay: 2s;}
.collect-bonus-item:nth-child(5) {animation-delay: 3s;}

@keyframes Active {
  0%, 24.99% {box-shadow: 0 0 100px 0 rgba(239, 68, 59, 0.4);}
  25%, 100% {box-shadow: 0 0 0 0 rgba(239, 68, 59, 0);}
}
<div class="collect-bonus-right">
  <div class="bebra">
    <p class="something">Steps to start traiding</p>
  </div>
  <div class="collect-bonus-item" id="one">
    <div class="circle">01</div>
    <p class="collect-bonus-item-text">Download platfrom</p>
  </div>
  <div class="collect-bonus-item" id="two">
    <div class="circle">02</div>
    <p class="collect-bonus-item-text">Create an account</p>
  </div>
  <div class="collect-bonus-item" id="three">
    <div class="circle">03</div>
    <p class="collect-bonus-item-text">Select the crypto</p>
  </div>
  <div class="collect-bonus-item" id="four">
    <div class="circle">04</div>
    <p class="collect-bonus-item-text">Start traiding</p>
  </div>
</div>

→ Ссылка