Простой таймер обратного отсчета на JavaScript

28 сентября 2022

Делаем на ванильном JavaScript таймер обратного отсчета до определенной даты или времени с функцией отображения контента по его завершении.

Еще в середине прошлого десятилетия редкий лендинг или интернет-магазин обходился без таймера обратного отсчета. Маркетологи считали, что все вокруг дебилы и такой таймер непременно сподвигнет посетителя на покупку. Удивительно, но этот прием можно встретить и по сей день. Причем не на каких-то конченых сайтах по продаже инфоцыганских говнокурсов, а на вполне серьезных ресурсах. Ну, да ладно, возможно я просто ничего в этом не смыслю. Таймер обратного отсчета применим не только для продажи разного шлака, его можно использовать и в мирных целях. Например, для задержки вывода какого-то контента, для улучшения поведенческих факторов и т.п. Естественно, можно использовать и по его прямому назначению: отсчету времени до какого-то события. Не мнимой 99% скидки, а действительно некоего реального события.

В результате должна получиться вот такая красота (для перезапуска нажмите Rerun).

See the Pen Countdown Timer to display content by Envato Tuts+ (@tutsplus) on CodePen.

Создаем разметку

Обновляемый контент разместим в элементах с ролью timer.

<section id="timer">
  <p>This content will be displayed in</p>
  <div class="timer-container">
    <span id="days" role="timer">0 days</span>
    <span id="hours" role="timer">0 hours</span>
    <span id="minutes" role="timer">0 minutes</span>
    and
    <span id="seconds" role="timer">0 seconds</span>
  </div>
</section>
 
<section id="content">
  <h1>Hello, World</h1>
</section>

Стилизуем

Для контента задаем opacity: 0, чтобы скрыть его на старте.

#timer {
  position: fixed;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  justify-content: center;
  align-items: center;
  width: 100%;
  z-index: 2;
}
 
#content {
  opacity: 0;
}

Делаем логику

Определить значение в виде конкретной даты и времени.

let countdownDate = new Date('01 January 2023 00:00')

Таймер можно инициализировать, добавив время к текущей дате.
Например, 30 секунд.

let countdownDate = new Date().setSeconds(new Date().getSeconds() + 30);

Секунды можно изменить на минуты или часы.

let countdownDate = new Date().setMinutes(new Date().getMinutes() + 5);
let countdownDate = new Date().setHours(new Date().getHours() + 1)

Функция startCountdown() получает текущую дату и вычитает ее из даты обратного отсчета.

const startCountdown = () => {
  const now = new Date().getTime();
  const countdown = new Date(countdownDate).getTime();
 
  const difference = (countdown - now) / 1000;
 
  let days = Math.floor(difference / (60 * 60 * 24));
  let hours = Math.floor((difference % (60 * 60 * 24)) / (60 * 60));
  let minutes = Math.floor((difference % (60 * 60)) / 60);
  let seconds = Math.floor(difference % 60);
 
  daysElem.innerHTML = formatTime(days, "day");
  hoursElem.innerHTML = formatTime(hours, "hour");
  minutesElem.innerHTML = formatTime(minutes, "minute");
  secondsElem.innerHTML = formatTime(seconds, "second");
};

Выполняем ее каждую секунду.

window.addEventListener("load", () => {
  startCountdown();
  timerInterval = setInterval(startCountdown, 1000);
});

До момента когда разница с startCountdown будет менее одной секунды.

const startCountdown = () => {
  const now = new Date().getTime();
  const countdown = new Date(countdownDate).getTime();
 
  const difference = (countdown - now) / 1000;
 
  if (difference < 1) {
    endCountdown();
  }
   
  ...
};

Должно получиться так.

See the Pen Countdown Timer by Envato Tuts+ (@tutsplus) on CodePen.

Чтобы по завершении работы таймера вывести контент, в функции endCountdown() останавливаем таймер и делаем контентный блок видимым.

const endCountdown = () => {
  clearInterval(timerInterval);
  timer.remove();
  content.classList.add("visible");
};

И добавим такой CSS.

#content h1 {
  font-size: 10vmax;
  transform: scale(1.25);
}
 
#content.visible {
  opacity: 1;
  animation: colorChange 1s ease-in-out 0.5s forwards;
}
 
#content.visible h1 {
  animation: scaleOut 1s ease-in-out 0.5s forwards;
}
 
@keyframes colorChange {
  from {
    color: #fcdf00;
    background-color: #0d67ad;
  }
  to {
    color: white;
    background-color: black;
  }
}
 
@keyframes scaleOut {
  from {
    transform: scale(1.25);
  }
  to {
    transform: scale(1);
  }
}

В итоге должно получиться так.

See the Pen Countdown Timer to display content by Envato Tuts+ (@tutsplus) on CodePen.

По материалам сайта tutsplus.com.
Иван Данилин
Автор Иван Данилин

Делаю сайты на Вордпресс с 2008 года, в том числе уникальные инструменты для решения сложных бизнес‑задач.

Добавить комментарий