простой обратный отсчет до Хэллоуина

Я только начал изучать JavaScript, и я сделал этот код ниже для простого обратного отсчета до проекта Хэллоуина.

// Setting counter start date
const year = new Date().getFullYear()

let timeInterval
let countdownWasStarted = false
let deadline = new Date("Oct 31, " + year)

// Function that starts the counter
function initCountdown() {

    // Stores the total time in milliseconds until halloween
    const untilH = (deadline - new Date())

    // Check if the year is a leap year and if the start date has expired
    const isLeapYear = !((year % 4) && (year % 100) || !(year % 400))
     
    if (year != isLeapYear && untilH <= 0) {
        deadline = new Date(deadline.getTime() + 365 * 24 * 60 * 60 * 1000)
        countdownWasStarted = true
        updateTime()
    }

    else if (year == isLeapYear && untilH.total <= 0) {
        deadline = new Date(deadline.getTime() + 366 * 24 * 60 * 60 * 1000)
        countdownWasStarted = true
        updateTime()
    }
    // Run the updateTime function every 1 second
    timeInterval = setInterval(updateTime, 1000)
}

// Converts days, hours, minutes and seconds to singular when they should be singular
function singular(value, singular, plural) {

    if(value == 1) {
        return singular
    } else {
        plural = singular + "s"
        return plural
    }
}

// Reset the counter
function resetCountdown() {
    
    clearInterval(timeInterval)
    initCountdown()
}

// Function that manipulates the DOM and calculates the days, hours, minutes and seconds until halloween
function updateTime() {

        // Stores the total time in milliseconds until halloween
        const untilHalloween = (deadline - new Date())

        // Stores the current year of the deadline variable
        const deadlineYear = deadline.getFullYear()

        // If the counter has expired, call the resetCountdown function to reset it
        if(countdownWasStarted == false && deadlineYear == year && untilHalloween <= 0) {
            resetCountdown()
        }
        // If the counter has already restarted, reset the variable countdownWasStarted to false
        else if(deadlineYear != year && countdownWasStarted != false) {
            countdownWasStarted = !countdownWasStarted
        }

        // Calculating days, hours, minutes and seconds
        const days = Math.floor(untilHalloween / (24*60*60*1000))
        const hours = Math.floor(untilHalloween / (60*60*1000)) % 24
        const minutes = Math.floor(untilHalloween / (60*1000)) % 60
        const seconds = Math.floor(untilHalloween / 1000) % 60
    
        let displayDays = `${singular(days, "day")}`
        let displayHours = `${singular(hours, "hour")}`
        let displayMinu = `${singular(minutes, "minute")}`
        let displaySecs = `${singular(seconds, "second")}`

    
          document.getElementById('singularD').innerHTML = displayDays
          document.getElementById('singularH').innerHTML = displayHours
          document.getElementById('singularM').innerHTML = displayMinu
          document.getElementById('singularS').innerHTML = displaySecs
    
    
          document.getElementById('days').innerHTML = days
          document.getElementById('hours').innerHTML = hours
          document.getElementById('minutes').innerHTML = minutes
          document.getElementById('seconds').innerHTML = seconds
}

// initial call
initCountdown()

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

Если вы, ребята, можете помочь мне с этим, я был бы очень благодарен 🙂

1 ответ
1

Я только просмотрел это и не понял на 100%, особенно смысл переменной countdownHasStarted -, но я заметил ошибку. Вы тестировали как с високосными, так и с невисокосными годами?

В initCountdown поскольку year является числовым значением и isLeapYear является логическим значением выражение year == isLeapYear всегда будет возвращаться false.


Как правило, вы всегда должны использовать === вместо == если у вас нет уважительной причины.


Вы «прячетесь» initCountdown() в конце кода. С function «подъемники» объявленную функцию, вы можете вызвать initCountdown() сразу после ваших объявлений переменных.


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


Вы не используете Date класс оптимально.

В качестве второстепенного момента вместо использования синтаксического анализа строк в new Date("Oct 31, " + year) было бы более прямолинейно использовать вариант new Date(year, month, day) и передать данные в виде чисел: new Date(year, 9, 31) (Обратите внимание, октябрь 9 так как счет начинается с 0 за январь). Или вместо создания нового Date объект, просто измените существующий:

let deadline = new Date();
deadline.setUTCMonth(9, 31);

const year = deadline.getFullYear();

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

deadline.setFullYear(deadline.getFullYear() + 1);

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


Вам не нужно использовать строковые шаблоны (`...`), если он содержит только одно выражение: ̀`${singular(days, "day")}` может быть просто singular(days, "day").


Функция singluar не должен был plural как параметр, а как локальная переменная (или просто return singular + "s";)


Вместо того, чтобы звонить document.getElementById() в каждом цикле вы должны вызывать и сохранять ссылки на элементы один раз в начале скрипта.


Использовать textContent вместо innerHTML при написании простого текста.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *