создание анимации с помощью setTimeout, потому что я хотел добавить задержку в анимацию, но она ведет себя странно - PullRequest
0 голосов
/ 07 мая 2020

вот код, который я написал, как вы можете видеть, когда триггер достигает красной линии, поля начинают менять цвет на красный, но когда триггер снова проходит красную линию, некоторые из полей меняют цвет на красный снова.

function what() {
  const trigger1 = document.querySelector(".trigger1").getBoundingClientRect().y;
  const element = document.querySelectorAll(".ele");

  if (trigger1 < 100) {
    function why() {
      for (let i = 0; i < element.length; i++) {
        setTimeout(() => {
          element[i].classList.add('newColor');
        }, i * 500)
      }
    }

    why();
  } else {
    element.forEach((e) => {
      e.classList.remove('newColor');
    })
  }

}

window.addEventListener("scroll", what);
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  font-size: 62.5%;
}

h1 {
  background-color: lightcoral;
  text-align: center;
  padding: 1rem;
  font-size: 2.5rem;
}

section {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

ul {
  position: fixed;
  top: 50%;
  left: 20%;
  transform: translate(-50%, -50%);
  text-align: center;
  list-style: none;
}

ul li {
  margin: 1rem;
  padding: 1rem;
  font-size: 2rem;
  background-color: rgb(134, 146, 211);
}

.newColor {
  color: white;
  background-color: red;
}

.line {
  position: fixed;
  top: 100px;
  width: 100%;
  height: 1px;
  background-color: red;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>

  <section>
    <div class="line"></div>
    <div>
      <h1 class="trigger1">here's the trigger</h1>
      <ul>
        <li class="ele">ayyyo</li>
        <li class="ele">woooo</li>
        <li class="ele">yoooo</li>
        <li class="ele">loool</li>
      </ul>
    </div>
  </section>

  <section>
    <div>
      <h1 class="trigger2">this is trigger 2</h1>
    </div>
  </section>

</body>

</html>

то, что я хочу сделать, - это когда триггер достигает красной линии, поля меняют цвет на красный. После этого, когда триггер возвращается в исходное положение (или оставляет красную линию внизу), поля меняют цвет на исходный цвет и никогда не меняют цвет на красный, если триггер снова не коснется красной линии.

нужно использовать clearTimeout, но не знаю, где и как его поставить.

было бы здорово, если бы вы дадите мне знать, как я могу это решить ... спасибо

1 Ответ

0 голосов
/ 07 мая 2020

Вы можете использовать глобальную переменную в качестве обработчика тайм-аута для clearTimeout.

Попробуйте следующий код.

var timeOutHandler = [];
function what() {
    const trigger1 = document.querySelector(".trigger1").getBoundingClientRect().y;
    const element = document.querySelectorAll(".ele");

    if(trigger1 < 100){
        for(let i = 0; i < element.length; i++){
            if ( typeof timeOutHandler[i] === 'undefined'){
                timeOutHandler[i] = setTimeout(()=> {
                    element[i].classList.add('newColor');
                }, i *500);  
            }
        }
    } else {
        for (i = 0; i < timeOutHandler.length; i++ ){
            clearTimeout( timeOutHandler[i] );
            timeOutHandler[i] = undefined;
        }
        element.forEach((e) => {
            e.classList.remove('newColor');
        });
    }
}

window.addEventListener("scroll", what);

Объяснение:

Согласно вашему коду будет выполнен повторный setTimeout каждый раз, когда пользователь прокручивает.

Чтобы предотвратить повторение setTimeout, вы можете назначить обработчик каждому элементу и выполнять setTimeout только тогда, когда обработчик не определен. Таким образом, будет только 1 setTimeout для каждого элемента, когда триггер впервые попадет в красную строку.

И когда триггер вернется ниже красной линии, остановите и удалите все таймауты и назначьте undefined всем обработчикам.

...