Статьи

Создайте таймер обратного отсчета всего за 18 строк JavaScript

Иногда в жизни вам понадобятся часы обратного отсчета JavaScript для чего-то другого, чем устройство конца света. Если у вас есть событие, распродажа, продвижение по службе или игра, вы можете выиграть от создания часов в сыром JavaScript, а не от поиска ближайшего плагина. Хотя есть много отличных плагинов для часов, вот преимущества, которые вы получите от использования необработанного JavaScript:

  • Ваш код будет легким, потому что он будет иметь нулевые зависимости.
  • Ваш сайт будет работать лучше, потому что вам не нужно загружать внешние скрипты и таблицы стилей.
  • У вас будет больше контроля, потому что вы построите часы так, чтобы они вели себя именно так, как вы этого хотите (вместо того, чтобы пытаться согнуть плагин под свою волю).

Итак, без лишних слов, вот как сделать ваши собственные часы обратного отсчета всего за 18 строк JavaScript.

Основные часы: Обратный отсчет до определенной даты или времени

Вот краткий обзор шагов, необходимых для создания основных часов:

  • Установите действительную дату окончания.
  • Подсчитайте оставшееся время.
  • Преобразуйте время в пригодный для использования формат.
  • Вывод данных часов как объекта многократного использования.
  • Отобразите часы на странице и остановите часы, когда они достигнут нуля.

Установите действительную дату окончания

Во-первых, вам нужно установить правильную дату окончания. Это должна быть строка в любом из форматов, понятных JavaScript- методу Date.parse () . Например:

Формат ISO 8601 :

var deadline = '2015-12-31';

Краткий формат:

 var deadline = '31/12/2015';

Или длинный формат:

 var deadline = 'December 31 2015';

Каждый из этих форматов позволяет вам указать точное время (в часах, минутах и ​​секундах), а также часовой пояс (или смещение от UTC в случае дат ISO). Например:

 var deadline = 'December 31 2015 23:59:59 GMT+0200';

Вы можете прочитать больше о форматировании даты в JavaScript в этой статье .

Рассчитать оставшееся время

Следующим шагом является подсчет оставшегося времени. Чтобы это произошло, нам нужно написать функцию, которая принимает строку, представляющую данное время окончания (как описано выше), и вычисляет разницу между этим временем и текущим временем. Вот как это выглядит:

 function getTimeRemaining(endtime){
  var t = Date.parse(endtime) - Date.parse(new Date());
  var seconds = Math.floor( (t/1000) % 60 );
  var minutes = Math.floor( (t/1000/60) % 60 );
  var hours = Math.floor( (t/(1000*60*60)) % 24 );
  var days = Math.floor( t/(1000*60*60*24) );
  return {
    'total': t,
    'days': days,
    'hours': hours,
    'minutes': minutes,
    'seconds': seconds
  };
}

Сначала мы создаем переменную t Функция Date.parse() Это позволяет нам вычитать два раза друг от друга и получать промежуток времени между ними.

 var t = Date.parse(endtime) - Date.parse(new Date());

Преобразовать время в используемый формат

Теперь мы хотим преобразовать миллисекунды в дни, часы, минуты и секунды. Давайте использовать секунды в качестве примера:

 var seconds = Math.floor( (t/1000) % 60 );

Давайте разберемся, что здесь происходит.

  1. Разделите миллисекунды на 1000, чтобы преобразовать в секунды: (t/1000)
  2. Разделите общее количество секунд на 60 и возьмите оставшуюся часть — вам не нужны все секунды, а только те, которые остались после подсчета минут: (t/1000) % 60
  3. Округлите это число до ближайшего целого числа — потому что вам нужны полные секунды, а не доли секунд: Math.floor( (t/1000) % 60 )

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

Вывод данных часов как объекта многократного использования

С подготовленными днями, часами, минутами и секундами мы готовы вернуть данные в виде объекта многократного использования:

 return {
  'total': t,
  'days': days,
  'hours': hours,
  'minutes': minutes,
  'seconds': seconds
};

Этот объект позволяет вам вызвать вашу функцию и получить любое из рассчитанных значений. Вот пример того, как вы получите оставшиеся минуты:

 getTimeRemaining(deadline).minutes

Удобно, правда?

Показать часы и остановить их, когда он достигает нуля

Теперь, когда у нас есть функция, которая выводит оставшиеся дни, часы, минуты и секунды, мы можем построить наши часы. Сначала мы создадим следующий HTML-элемент для хранения наших часов:

 <div id="clockdiv"></div>

Затем мы напишем функцию, которая выводит данные часов внутри нашего нового div:

 function initializeClock(id, endtime){
  var clock = document.getElementById(id);
  var timeinterval = setInterval(function(){
    var t = getTimeRemaining(endtime);
    clock.innerHTML = 'days: ' + t.days + '<br>' +
                      'hours: '+ t.hours + '<br>' +
                      'minutes: ' + t.minutes + '<br>' +
                      'seconds: ' + t.seconds;
    if(t.total<=0){
      clearInterval(timeinterval);
    }
  },1000);
}

Эта функция принимает два параметра: идентификатор элемента, который будет содержать наши часы, и время окончания обратного отсчета. Внутри функции мы объявим переменную с именем clock

Далее мы будем использовать setInterval

  • Подсчитайте оставшееся время.
  • Выведите оставшееся время в наш div.
  • Если оставшееся время достигает нуля, остановите часы.

На данный момент, единственный оставшийся шаг — запустить часы следующим образом:

 initializeClock('clockdiv', deadline);

Поздравляем! Теперь у вас есть базовые часы всего в 18 строках JavaScript.

Подготовьте свои часы для показа

Прежде чем приступить к оформлению часов, нам нужно немного усовершенствовать вещи.

  • Удалите начальную задержку, чтобы ваши часы сразу появились.
  • Сделайте скрипт часов более эффективным, чтобы он не перестраивал непрерывно все часы.
  • Добавьте ведущие нули по желанию.

Удалить начальную задержку

В часах мы использовали setInterval Это нормально в большинстве случаев, кроме как в начале, когда будет задержка в одну секунду. Чтобы устранить эту задержку, нам нужно будет обновить часы один раз перед началом интервала.

Для этого давайте переместим анонимную функцию, которую мы передаем в setIntervalupdateClock Вызовите функцию updateClocksetIntervalsetInterval Таким образом, часы появляются без задержки.

В вашем JavaScript замените это:

 var timeinterval = setInterval(function(){ ... },1000);

С этим:

 function updateClock(){
  var t = getTimeRemaining(endtime);
  clock.innerHTML = 'days: ' + t.days + '<br>' +
                    'hours: '+ t.hours + '<br>' +
                    'minutes: ' + t.minutes + '<br>' +
                    'seconds: ' + t.seconds;
  if(t.total<=0){
    clearInterval(timeinterval);
  }
}

updateClock(); // run function once at first to avoid delay
var timeinterval = setInterval(updateClock,1000);

Избегайте постоянного восстановления часов

Чтобы сделать скрипт часов более эффективным, мы хотим обновлять только числа в часах, а не перестраивать все часы каждую секунду. Один из способов сделать это — поместить каждое число в тег span

Вот HTML-код:

 <div id="clockdiv">
    Days: <span class="days"></span><br>
    Hours: <span class="hours"></span><br>
    Minutes: <span class="minutes"></span><br>
    Seconds: <span class="seconds"></span>
</div>

Теперь давайте получим ссылку на эти элементы. Добавьте следующий код сразу после определения переменной clock

 var daysSpan = clock.querySelector('.days');
var hoursSpan = clock.querySelector('.hours');
var minutesSpan = clock.querySelector('.minutes');
var secondsSpan = clock.querySelector('.seconds');

Далее нам нужно изменить функцию updateClock Новый код будет выглядеть так:

 function updateClock(){
    var t = getTimeRemaining(endtime);

    daysSpan.innerHTML = t.days;
    hoursSpan.innerHTML = t.hours;
    minutesSpan.innerHTML = t.minutes;
    secondsSpan.innerHTML = t.seconds;

    ...
}

Добавить ведущие нули

Теперь, когда часы обновляют числа, а не восстанавливают каждую секунду, нам нужно сделать еще одну вещь: добавить начальные нули. Например, вместо того, чтобы часы показывали 7 секунд, они показывали бы 07 секунд. Один простой способ сделать это — добавить строку «0» в начало числа, а затем вырезать последние две цифры.

Например, чтобы добавить начальный ноль к значению «секунд», вы должны изменить это:

 secondsSpan.innerHTML = t.seconds;

к этому:

 secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

При желании вы можете добавить ведущие нули к минутам и часам. Если вы зашли так далеко, поздравляю! Ваши часы теперь готовы к показу.

Примечание: вам может потребоваться нажать «Rerun» в CodePen для начала обратного отсчета.

Продолжая

Следующие примеры демонстрируют, как расширить часы для определенных случаев использования. Все они основаны на базовом примере, приведенном выше.

Расписание часов автоматически

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

Скрыть часы, установив его свойство display Затем добавьте следующее в функцию noneinitializeClock Это заставит часы отображаться только после var clockinitializeClock

 clock.style.display = 'block';

Далее мы можем указать даты, между которыми должны появиться часы. Это заменит переменную deadline

 var schedule = [
    ['Jul 25 2015', 'Sept 20 2015'],
    ['Sept 21 2015', 'Jul 25 2016'],
    ['Jul 25 2016', 'Jul 25 2030']
];

Каждый элемент в массиве schedule Как отмечалось выше, можно включать время и часовые пояса, но я использовал простые даты, чтобы код был читабельным.

Наконец, когда пользователь загружает страницу, нам нужно проверить, находимся ли мы в каком-либо из указанных временных интервалов. Этот код должен заменить предыдущий вызов функции initializeClock

 // iterate over each element in the schedule
for(var i=0; i<schedule.length; i++){
  var startDate = schedule[i][0];
  var endDate = schedule[i][1];

  // put dates in milliseconds for easy comparisons
  var startMs = Date.parse(startDate);
  var endMs = Date.parse(endDate);
  var currentMs = Date.parse(new Date());

  // if current date is between start and end dates, display clock
  if(endMs > currentMs && currentMs >= startMs ){
      initializeClock('clockdiv', endDate);
  }
}

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

Обратный отсчет от того, когда пользователь прибывает

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

Все, что нам нужно сделать здесь, это заменить переменную deadline

 var timeInMinutes = 10;
var currentTime = Date.parse(new Date());
var deadline = new Date(currentTime + timeInMinutes*60*1000);

Этот код занимает текущее время и добавляет десять минут. Значения преобразуются в миллисекунды, поэтому их можно сложить вместе и превратить в новый срок.

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

Поддерживать ход часов по страницам

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

Одним из решений является сохранение времени окончания часов в cookie. Таким образом, переход на новую страницу не сбрасывает время окончания до десяти минут.

Вот логика:

  1. Если крайний срок был записан в куки, используйте этот крайний срок.
  2. Если файл cookie отсутствует, установите новый срок и сохраните его в файле cookie.

Чтобы реализовать это, замените переменную deadline

 // if there's a cookie with the name myClock, use that value as the deadline
if(document.cookie && document.cookie.match('myClock')){
  // get deadline value from cookie
  var deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
}

// otherwise, set a deadline 10 minutes from now and 
// save it in a cookie with that name
else{
  // create deadline 10 minutes from now
  var timeInMinutes = 10;
  var currentTime = Date.parse(new Date());
  var deadline = new Date(currentTime + timeInMinutes*60*1000);

  // store deadline in cookie for future reference
  document.cookie = 'myClock=' + deadline + '; path=/; domain=.yourdomain.com';
}

В этом коде используются файлы cookie и регулярные выражения , которые сами по себе являются отдельными темами. По этой причине я не буду вдаваться в подробности. Важно отметить, что вам нужно изменить .yourdomain.com Если у вас есть какие-либо вопросы по этому поводу, дайте мне знать в комментариях.

Важное предупреждение о времени на стороне клиента

JavaScript даты и время взяты с компьютера пользователя. Это означает, что пользователь может влиять на часы JavaScript, изменяя время на своем компьютере. В большинстве случаев это не имеет значения, но в случае чего-то сверхчувствительного, необходимо будет получить время с сервера. Это можно сделать с помощью небольшого количества PHP или Ajax, которые выходят за рамки данного руководства.

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

Вывод

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

Что дальше?

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