Mike_Ro
@Mike_Ro
Python, JS, WordPress, SEO, Bots, Adversting

Как вернуть setTimeout?

Приветствую!

Имеется element с css анимацией, по окончанию анимации запустить таймер. Если навели курсор на element, то сбросить таймер. Если увели курсор с element - вернуть таймер (вот тут и возникла проблема).

const timeout = setTimeout(() => console.log("timeout!"), 1000);
const fn = () => timeout;

element.addEventListener("animationend", fn);
element.addEventListener("mouseover", () => {
  element.removeEventListener("animationend", fn);
  clearTimeout(timeout);
});
element.addEventListener("mouseout", fn);


Снять таймер получилось, а вот вернуть его обратно - нет :(
Подскажите, как решить проблему, и как бы вы написали код для решения подобной задачи?
  • Вопрос задан
  • 264 просмотра
Решения вопроса 1
dollar
@dollar
Делай добро и бросай его в воду.
let is_paused = false;
const timeout = setTimeout(() => {
  if (is_paused) return;
  console.log("timeout!");
}, 1000);


Тогда снимать и возвращать таймер можно просто:
is_paused = true; //снять
is_paused = false; //вернуть


А вот это вообще не имеет смысла:
const fn = () => timeout;
Потому что timeout - число (номер таймера). Так что fn() всегда будет возвращать некую числовую константу, которую можно получить и так, обращаясь непосредственно к timeout, которая не меняется. То есть timeout - не ссылка на объект таймера, а просто число.

Возвращаемый идентификатор таймера (timeout) функцией setTimeout нужен только для того, чтобы иметь возможность остановить таймер полностью. Встроенных возможностей ставить на паузу и снова запускать - нет. Можно либо так, как я реализовал выше, через внешнюю переменную, либо каждый раз создавать новый таймер с новым идентификатором (и тогда timeout лучше сделать переменной, а не константой).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
const createPausableTimer = (cb, timeout, ...args) => {
  let lastStart = Date.now();
  let paused = false;
  let timerID = setTimeout(cb, timeout, ...args);
  let remainingTime = timeout;
  return {
    pause() {
      if(paused) { return; }
      clearTimeout(timerID);
      paused = true;
      remainingTime -= Date.now() - lastStart;
    },
    resume() {
      if(!paused || remainingTime < 0) { return; }
      lastStart = Date.now();
      paused = false;
      timerID = setTimeout(cb, remainingTime, ...args);
    }
  };
};

element.addEventListener("animationend", () => {
  const timer = createPausableTimer(() => {
    console.log("timeout!");
    element.removeEventListener("mouseover", timer.resume);
    element.removeEventListener("mouseout", timer.pause);
  }, 1000);
  element.addEventListener("mouseover", timer.resume);
  element.addEventListener("mouseout", timer.pause);
});
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы