Я только начал изучать 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 ответ
Я только просмотрел это и не понял на 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
при написании простого текста.
РоТора