Как получать значение из дата атрибута, которое будет подставляться в объект date?
есть таймер
в переменной deadline лежит значение к которой нужно отчитывать время
но если задавать время таким образом, но проблема будет с редактированием нужно как-то держать их в дата-атрибуте и потом как-то получать
document.addEventListener('DOMContentLoaded', function () {
// конечная дата
const deadline = new Date(2021, 10, 01, 18, 30);
// id таймера
let timerId = null;
// склонение числительных
function declensionNum(num, words) {
return words[(num % 100 > 4 && num % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][(num % 10 < 5) ? num % 10 : 5]];
}
// вычисляем разницу дат и устанавливаем оставшееся времени в качестве содержимого элементов
function countdownTimer() {
const diff = deadline - new Date();
if (diff <= 0) {
clearInterval(timerId);
}
const days = diff > 0 ? Math.floor(diff / 1000 / 60 / 60 / 24) : 0;
const hours = diff > 0 ? Math.floor(diff / 1000 / 60 / 60) % 24 : 0;
const minutes = diff > 0 ? Math.floor(diff / 1000 / 60) % 60 : 0;
const seconds = diff > 0 ? Math.floor(diff / 1000) % 60 : 0;
$days.textContent = days < 10 ? '0' + days : days;
$hours.textContent = hours < 10 ? '0' + hours : hours;
$minutes.textContent = minutes < 10 ? '0' + minutes : minutes;
$seconds.textContent = seconds < 10 ? '0' + seconds : seconds;
$days.dataset.title = declensionNum(days, ['день', 'дня', 'дней']);
$hours.dataset.title = declensionNum(hours, ['час', 'часа', 'часов']);
$minutes.dataset.title = declensionNum(minutes, ['минута', 'минуты', 'минут']);
$seconds.dataset.title = declensionNum(seconds, ['секунда', 'секунды', 'секунд']);
}
// получаем элементы, содержащие компоненты даты
const $days = document.querySelector('.timer__days');
const $hours = document.querySelector('.timer__hours');
const $minutes = document.querySelector('.timer__minutes');
const $seconds = document.querySelector('.timer__seconds');
// вызываем функцию countdownTimer
countdownTimer();
// вызываем функцию countdownTimer каждую секунду
timerId = setInterval(countdownTimer, 1000);
});
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
background-color: #fff;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
display: flex;
justify-content: center;
}
.timer__items {
display: flex;
font-size: 48px;
}
.timer__item {
position: relative;
min-width: 60px;
margin-left: 10px;
margin-right: 10px;
padding-bottom: 15px;
text-align: center;
}
.timer__item::before {
content: attr(data-title);
display: block;
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
font-size: 14px;
}
.timer__item:not(:last-child)::after {
content: ':';
position: absolute;
right: -15px;
}
<div class="timer" data-time="01.10.2021 18:30">
<div class="timer__items">
<div class="timer__item timer__days">00</div>
<div class="timer__item timer__hours">00</div>
<div class="timer__item timer__minutes">00</div>
<div class="timer__item timer__seconds">00</div>
</div>
</div>
Ответы (1 шт):
Значения, которые задаются через data-* атрибуты доступны через свойство dataset у объекта типа HTMLElement:
const deadlineStr = document.querySelector('.timer').dataset.time;
Далее для получения объекта типа Date из строки можно воспользоваться функцией Date.parse, но дата из примера (01.10.2021 18:30) парсится не так, как ожидается: Sun Jan 10 2021 18:30:00 (месяц и день перепутаны).
Поэтому можно либо написать свой парсер для указанного формата даты, либо использовать формат даты, который распарсится методом Date.parse, либо как вариант вообще через дата атрибут прокидывать уже timestamp и не делать промежуточный парсинг.
Парсер текущего формата даты мог бы выглядеть так:
const parseDate = dateStr => {
const [date, time] = dateStr.split(' ');
const [day, month, year] = date.split('.').map(Number);
const [hours, minutes] = time.split(':').map(Number);
return new Date(year, month - 1, day, hours, minutes);
}