Один из стандартных инструментов, который вам нужно знать, как делать в JavaScript, это… как управлять временем. Чтобы продемонстрировать это, мы создадим таймер обратного отсчета, используя ванильный JavaScript и CSS.

Это простой проект, но он показывает, как управлять временем в JS, настраивать атрибуты в CSS и, наконец, добавлять пользовательские параметры в свой класс JS.


Посмотреть это на YouTube



Структура файла

index.html
/sass
     style.scss
/js
     init.js
     countdown.js
/css (generated by Sass)
   style.css
   style.min.css
Войти в полноэкранный режим

Выйти из полноэкранного режима


Наш HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Countdown Clocks</title>
    <link rel="stylesheet" href="/css/style.min.css">
</head>
<body>
    <h2>Countdown Clock 1</h2>
    <div class="clock" id="clock1">
        <div data-value="days"></div>
        <div data-value="hours"></div>
        <div data-value="minutes"></div>
        <div data-value="seconds"></div>
    </div>
    <script src="/js/countdown.js"></script>
    <script src="/js/init.js"></script>
</body>
</html>
Войти в полноэкранный режим

Выйти из полноэкранного режима

Теперь, когда у нас есть базовая структура HTML, мы можем создать класс JS, который добавляет данные. Обратите внимание, что мы используем data-value поэтому нам не нужно добавлять строку в HTML, мы изменим это в CSS.


Наш класс обратного отсчета JS

// class to create a countdown timer
class CountdownTimer {
    // setup timer values
    constructor({ selector, targetDate, backgroundColor = null, foregroundColor = null }) {
        this.selector = selector;
        this.targetDate = targetDate;
        this.backgroundColor = backgroundColor;
        this.foregroundColor = foregroundColor;

        // grab divs on frontend using supplied selector ID
        this.refs = {
            days: document.querySelector(`${this.selector} [data-value="days"]`),
            hours: document.querySelector(`${this.selector} [data-value="hours"]`),
            mins: document.querySelector(`${this.selector} [data-value="minutes"]`),
            secs: document.querySelector(`${this.selector} [data-value="seconds"]`),
        };
    }

    getTimeRemaining(endtime) {
        const total = Date.parse(endtime) - Date.parse(new Date());
        const days = Math.floor(total / (1000 * 60 * 60 * 24));
        const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
        const mins = Math.floor((total / 1000 / 60) % 60);
        const secs = Math.floor((total / 1000) % 60);
        return {
            total,
            days,
            hours,
            mins,
            secs,
        };
    }

    updateTimer({ days, hours, mins, secs }) {
        this.refs.days.textContent = days;
        this.refs.hours.textContent = hours;
        this.refs.mins.textContent = mins;
        this.refs.secs.textContent = secs;
    }

    updateColors() {
        if (this.backgroundColor != null) {
            this.refs.days.style.background = this.backgroundColor;
            this.refs.hours.style.background = this.backgroundColor;
            this.refs.mins.style.background = this.backgroundColor;
            this.refs.secs.style.background = this.backgroundColor;
        }

        if (this.foregroundColor != null) {
            this.refs.days.style.color = this.foregroundColor;
            this.refs.hours.style.color = this.foregroundColor;
            this.refs.mins.style.color = this.foregroundColor;
            this.refs.secs.style.color = this.foregroundColor;
        }
    }

    startTimer() {
        const timer = this.getTimeRemaining(this.targetDate);
        this.updateTimer(timer);
        this.updateColors();
        setInterval(() => {
            const timer = this.getTimeRemaining(this.targetDate);
            this.updateTimer(timer);
        }, 1000);
    }
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Этот класс будет управлять div а также data-values нам нужно заменить. Мы создаем это как класс, поэтому мы можем просто добавить несколько строк кода, чтобы добавить обратный отсчет на любой странице через наш init.js файл.

Этот класс занимает selector, targetDateи необязательно backgroundColor а также foregroundColor. Мы будем передавать эти значения при вызове класса.


Вызов нашего класса

В твоей init.js файл, вы можете вызвать класс обратного отсчета, используя что-то вроде этого:

const timer = new CountdownTimer({
    selector: "#clock1",
    targetDate: new Date("September, 21 2022 18:00:00"),
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

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

const timer = new CountdownTimer({
    selector: "#clock1",
    targetDate: new Date("September, 21 2022 18:00:00"),
    backgroundColor: "rgba(0,0,0,.15)",
    foregroundColor: "rgba(0,0,0,.50)",
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

Вы должны использовать цвета фона и переднего плана, если вы настраиваете один или другой. Мы настроили его на нулевое значение, но, в конце концов, если вы используете одно, вы должны использовать и другое.

Это так просто. Теперь, когда вы настроили свой класс, вы можете добавить свой обратный отсчет в любой div, который вы хотите. Вы также можете добавить несколько обратных отсчетов на одной странице. Например:

<h2>Countdown Clock 1</h2>
<div class="clock" id="clock1">
    <div data-value="days"></div>
    <div data-value="hours"></div>
    <div data-value="minutes"></div>
    <div data-value="seconds"></div>
</div>

<h2>Countdown Clock 2</h2>
<div class="clock" id="clock2">
    <div data-value="days"></div>
    <div data-value="hours"></div>
    <div data-value="minutes"></div>
    <div data-value="seconds"></div>
</div>
Войти в полноэкранный режим

Выйти из полноэкранного режима

// setup timer with set textual date in the future
const timer1 = new CountdownTimer({
    selector: "#clock1",
    targetDate: new Date("September, 21 2022 18:00:00"),
});

// setup timer with date set in the future
const timer2 = new CountdownTimer({
    selector: "#clock2",
    targetDate: new Date("September, 21 2022 18:00:00"),
    backgroundColor: "rgba(0,0,0,.15)",
    foregroundColor: "rgba(0,0,0,.50)",
});
Войти в полноэкранный режим

Выйти из полноэкранного режима

Примечание Чтобы использовать этот класс на нескольких элементах div, вы должны передать уникальный selector который соответствует идентификатору div. В этом случае мы используем #clock1 а также #clock2 который соответствует нашим идентификаторам div.


Наши стили обратного отсчета

Эта часть довольно стандартна, если вы когда-либо использовали CSS или Sass. Обратите внимание, что в Sass мы настраиваем разделы обратного отсчета, используя их data-value атрибут. Здесь мы добавляем текст для нашего div (дни, часы, минуты, секунды).

body {
    background-color: #38a4ef;
    color:#fff;
    font-size:16px;
    text-align:center;
    font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
}

.clock {
    display:block;
    margin: 0 auto;
    max-width:80%;
    div {
        background-color:rgba(255,255,255,.25);
        color:#fff;
        display:inline-block;
        padding:2rem;
        margin: 0 1rem;
        font-size:2.5rem;
        width: calc(10% - 2rem);
        text-align:center;
        font-weight:bold;
        border-radius:5%;
        &[data-value*="days"]:after, &[data-value*="hours"]:after, &[data-value*="minutes"]:after, &[data-value*="seconds"]:after {
            display:block;
            font-size:.75rem;
            margin-top:.25rem;
            font-weight: 300;
        }
        &[data-value*="days"]:after {
            content:"Days"
        }
        &[data-value*="hours"]:after {
            content:"Hours"
        }
        &[data-value*="minutes"]:after {
            content:"Minutes"
        }
        &[data-value*="seconds"]:after {
            content:"Seconds"
        }
    }
}

@media screen and (max-width: 820px) {
    .clock {
        max-width:90%;
        div {
            width:calc(15% - 2rem)
        }
    }
}

@media screen and (max-width: 767px) {
    .clock {
        max-width:100%;
        div {
            width:calc(30% - 4rem);
            margin:.5rem;
            padding: .5rem;
            font-size:1rem;
            &[data-value*="days"]:after, &[data-value*="hours"]:after, &[data-value*="minutes"]:after, &[data-value*="seconds"]:after {
                font-size:.5rem;
            }
        }
    }
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Мы просто используем селектор CSS :after, чтобы добавить слова в div. Это избавляет нас от необходимости редактировать его каждый раз, когда мы размещаем его на странице.

Я также добавил адаптивные медиа-запросы в нашу таблицу стилей Sass, чтобы она работала на планшетах и ​​мобильных телефонах.


Вывод

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