Как сделать онлайн-таймер: пошаговая разработка для управления временем

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Начинающие программисты и веб-разработчики, желающие улучшить свои навыки.
  • Студенты и участники курсов по веб-разработке, ищущие практические проекты для обучения.
  • Разработчики, интересующиеся созданием интерактивных веб-приложений и интерфейсов.

    Создание онлайн-таймера — это не просто упражнение для развития навыков кодирования, а полноценный проект, который демонстрирует ваше понимание взаимодействия HTML, CSS и JavaScript. В мире, где продуктивность ценится на вес золота, таймеры стали незаменимыми помощниками. 🕒 Будь то таймер для техники Pomodoro, счетчик для интервальных тренировок или просто обратный отсчет до дедлайна — умение создать такой инструмент собственными руками значительно обогатит ваше портфолио разработчика и расширит технический арсенал.

Хотите не просто следовать инструкциям, а полностью понимать принципы веб-разработки? Курс Обучение веб-разработке от Skypro даст вам больше, чем просто навыки кодирования. Вы научитесь создавать интерактивные веб-приложения, включая таймеры различной сложности, под руководством практикующих разработчиков. Через 9 месяцев вы превратитесь из новичка в разработчика, способного решать реальные задачи и создавать впечатляющие проекты для своего портфолио.

Основы создания онлайн таймера: что нужно знать

Перед тем как погрузиться в код, важно понять основные принципы и компоненты, которые составляют функциональный онлайн-таймер. Таймер — это не просто цифры на экране, а интерактивное приложение, требующее чёткой логики и отзывчивого пользовательского интерфейса.

Начнем с определения ключевых функциональных требований к нашему таймеру:

  • Отображение времени в формате часы:минуты:секунды
  • Кнопки управления (старт, пауза, сброс)
  • Возможность ввода пользовательского времени
  • Визуальное и/или звуковое оповещение по окончании отсчета
  • Адаптивный дизайн для различных устройств

Для создания таймера нам потребуются следующие технологии и концепции:

Технология Применение в проекте
HTML Структура таймера и элементы управления
CSS Стилизация интерфейса и анимации
JavaScript Логика отсчета времени и интерактивность
Date объект Манипуляции со временем
setInterval()/setTimeout() Обновление таймера каждую секунду

Александр Петров, Senior Frontend-разработчик

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

Я начал с простой HTML-структуры и базовой JavaScript-логики. Но по мере работы понял, что этот проект — идеальная возможность продемонстрировать, как frontend-элементы могут создавать эмоциональную связь с пользователем. Добавив градиентные переходы цвета по мере приближения нуля, тонкие анимации CSS и тактильную отдачу через API вибрации для мобильных, мы превратили обычный таймер в маленькое событие, которое удерживало внимание аудитории.

Теперь рассмотрим общую архитектуру нашего таймера. Мы будем использовать объектно-ориентированный подход, где таймер — это объект со своими свойствами (текущее время) и методами (старт, пауза, сброс). Такой подход сделает наш код более организованным и расширяемым в будущем.

Ключевой вопрос, который нужно решить при разработке таймера — как обрабатывать время? Есть два основных подхода:

  1. Отсчет от заданного времени вниз — мы устанавливаем начальное значение и каждую секунду вычитаем 1.
  2. Вычисление разницы между текущим временем и целевым временем — более точный метод, но требует дополнительных вычислений.

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

Пошаговый план для смены профессии

Разработка HTML-структуры для таймера обратного отсчета

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

Начнем с создания базовой структуры нашего таймера:

HTML
Скопировать код
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Онлайн-таймер</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="timer-container">
<h1>Онлайн-таймер</h1>

<div class="timer-setup">
<div class="input-group">
<input type="number" id="hours" min="0" max="23" value="0">
<label for="hours">Часы</label>
</div>
<div class="input-group">
<input type="number" id="minutes" min="0" max="59" value="0">
<label for="minutes">Минуты</label>
</div>
<div class="input-group">
<input type="number" id="seconds" min="0" max="59" value="0">
<label for="seconds">Секунды</label>
</div>
</div>

<div class="timer-display">
<div class="time-segment">
<span id="display-hours">00</span>
<span class="label">Часы</span>
</div>
<div class="separator">:</div>
<div class="time-segment">
<span id="display-minutes">00</span>
<span class="label">Минуты</span>
</div>
<div class="separator">:</div>
<div class="time-segment">
<span id="display-seconds">00</span>
<span class="label">Секунды</span>
</div>
</div>

<div class="timer-controls">
<button id="start">Старт</button>
<button id="pause" disabled>Пауза</button>
<button id="reset">Сброс</button>
</div>

<div class="timer-notification" id="notification">
Время истекло!
</div>
</div>

<script src="timer.js"></script>
</body>
</html>

Давайте разберем каждый блок нашей HTML-структуры более подробно:

  1. timer-container — главный контейнер, объединяющий все элементы таймера
  2. timer-setup — содержит поля ввода для установки начального времени
  3. timer-display — отображает текущее состояние таймера в формате ЧЧ:ММ:СС
  4. timer-controls — содержит кнопки управления таймером
  5. timer-notification — элемент для отображения уведомления о завершении отсчета

Обратите внимание на атрибуты id для каждого элемента — они будут использоваться в JavaScript для взаимодействия с DOM-элементами. Также важно правильно структурировать входные поля с минимальными и максимальными значениями, чтобы предотвратить ввод некорректных данных (например, 70 секунд или -5 часов). 🛡️

Для обеспечения доступности (accessibility) мы связали метки (label) с соответствующими полями ввода и добавили семантически корректные элементы. Это важно не только для пользователей с особыми потребностями, но и для SEO-оптимизации.

Элемент HTML Назначение Атрибуты для JavaScript
input[type="number"] Ввод числовых значений времени id="hours", id="minutes", id="seconds"
span (в timer-display) Отображение текущего времени id="display-hours", id="display-minutes", id="display-seconds"
button Элементы управления таймером id="start", id="pause", id="reset"
div.timer-notification Отображение сообщения о завершении id="notification"

При проектировании HTML-структуры таймера важно учитывать взаимодействие пользователя с интерфейсом. Например, мы изначально делаем кнопку "Пауза" неактивной (атрибут disabled), так как до запуска таймера она не имеет смысла.

Стилизация таймера с помощью CSS: дизайн и адаптивность

После создания HTML-структуры пришло время превратить наш скелет в привлекательный и функциональный интерфейс с помощью CSS. Хорошо спроектированный таймер должен быть не только эстетичным, но и интуитивно понятным для пользователя. 🎨

Создадим файл styles.css и добавим в него следующий код:

CSS
Скопировать код
/* Глобальные стили и сброс */
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}

body {
font-family: 'Arial', sans-serif;
background-color: #f5f5f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: #333;
}

/* Основной контейнер таймера */
.timer-container {
background: white;
border-radius: 10px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
padding: 30px;
width: 90%;
max-width: 500px;
text-align: center;
}

h1 {
margin-bottom: 25px;
color: #2c3e50;
font-size: 28px;
}

/* Настройка времени */
.timer-setup {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
}

.input-group {
display: flex;
flex-direction: column;
width: 30%;
}

.input-group label {
font-size: 14px;
margin-top: 8px;
color: #7f8c8d;
}

.input-group input {
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
text-align: center;
font-size: 18px;
}

/* Отображение таймера */
.timer-display {
display: flex;
justify-content: center;
align-items: center;
margin: 30px 0;
padding: 20px;
background-color: #ecf0f1;
border-radius: 8px;
}

.time-segment {
display: flex;
flex-direction: column;
align-items: center;
}

.time-segment span:first-child {
font-size: 42px;
font-weight: bold;
color: #3498db;
}

.time-segment .label {
font-size: 12px;
color: #95a5a6;
margin-top: 5px;
}

.separator {
font-size: 42px;
font-weight: bold;
margin: 0 10px;
color: #7f8c8d;
align-self: flex-start;
}

/* Кнопки управления */
.timer-controls {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 20px;
}

button {
padding: 12px 25px;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s, transform 0.1s;
}

button:active {
transform: scale(0.98);
}

#start {
background-color: #2ecc71;
color: white;
}

#start:hover {
background-color: #27ae60;
}

#pause {
background-color: #e74c3c;
color: white;
}

#pause:hover:not([disabled]) {
background-color: #c0392b;
}

#pause[disabled] {
background-color: #95a5a6;
cursor: not-allowed;
}

#reset {
background-color: #3498db;
color: white;
}

#reset:hover {
background-color: #2980b9;
}

/* Уведомление о завершении */
.timer-notification {
background-color: #e74c3c;
color: white;
padding: 15px;
border-radius: 5px;
margin-top: 20px;
display: none;
animation: pulse 1.5s infinite;
}

@keyframes pulse {
0% { opacity: 0.7; }
50% { opacity: 1; }
100% { opacity: 0.7; }
}

/* Адаптивность для различных устройств */
@media (max-width: 500px) {
.timer-container {
padding: 20px;
}

.time-segment span:first-child {
font-size: 32px;
}

.separator {
font-size: 32px;
margin: 0 5px;
}

button {
padding: 10px 15px;
font-size: 14px;
}
}

@media (max-width: 350px) {
.timer-setup {
flex-direction: column;
align-items: center;
gap: 15px;
}

.input-group {
width: 80%;
}
}

Мария Смирнова, UX/UI дизайнер

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

Когда мы использовали красные тона и быстрые анимации для таймера Pomodoro, пользователи субъективно ощущали, что 25-минутный рабочий интервал проходит быстрее. Напротив, спокойные синие оттенки и плавные переходы для таймера отдыха создавали ощущение более длительной паузы, хотя фактически она составляла всего 5 минут.

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

Разберем ключевые аспекты нашей CSS-стилизации:

  • Цветовая схема — используем контрастные цвета для различных состояний и функций таймера
  • Визуальная иерархия — наиболее важные элементы (текущее время) выделены размером и цветом
  • Отзывчивый дизайн — таймер адаптируется под различные размеры экранов
  • Микроанимации — добавляют живость интерфейсу (пульсация уведомления, небольшое нажатие кнопок)
  • Доступность — достаточный контраст, четкие визуальные различия между активными и неактивными элементами

Особое внимание уделим адаптивности нашего таймера. Мы используем относительные единицы измерения и медиа-запросы для обеспечения корректного отображения на устройствах с разными размерами экрана. При ширине экрана менее 500px мы уменьшаем размер шрифта и отступы, а при ширине менее 350px меняем расположение элементов ввода с горизонтального на вертикальное.

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

Не забывайте о состояниях взаимодействия (hover, active, disabled) для интерактивных элементов. Они обеспечивают визуальную обратную связь и улучшают пользовательский опыт. Например, кнопка "Пауза" в неактивном состоянии имеет серый цвет и курсор "not-allowed", чтобы явно показать пользователю, что функция недоступна.

JavaScript-логика: программирование функций таймера

Теперь, когда у нас есть структура и стиль, пришло время добавить функциональность нашему таймеру с помощью JavaScript. Именно JS-логика превратит статичную страницу в динамическое приложение, способное вести обратный отсчет и реагировать на действия пользователя. 💻

Создадим файл timer.js и реализуем следующую логику:

JS
Скопировать код
// Получаем доступ к DOM-элементам
const hoursInput = document.getElementById('hours');
const minutesInput = document.getElementById('minutes');
const secondsInput = document.getElementById('seconds');

const displayHours = document.getElementById('display-hours');
const displayMinutes = document.getElementById('display-minutes');
const displaySeconds = document.getElementById('display-seconds');

const startButton = document.getElementById('start');
const pauseButton = document.getElementById('pause');
const resetButton = document.getElementById('reset');
const notification = document.getElementById('notification');

// Объект таймера с его состоянием и методами
const timer = {
intervalId: null,
totalSeconds: 0,
isRunning: false,

// Метод запуска таймера
start: function() {
if (!this.isRunning) {
// Получаем значения из полей ввода и конвертируем в секунды
const hours = parseInt(hoursInput.value) || 0;
const minutes = parseInt(minutesInput.value) || 0;
const seconds = parseInt(secondsInput.value) || 0;

this.totalSeconds = hours * 3600 + minutes * 60 + seconds;

// Проверяем, что введено положительное время
if (this.totalSeconds <= 0) {
alert('Пожалуйста, установите положительное значение времени!');
return;
}

// Обновляем отображение и запускаем интервал
this.updateDisplay();
this.isRunning = true;
startButton.disabled = true;
pauseButton.disabled = false;

this.intervalId = setInterval(() => {
this.tick();
}, 1000);
}
},

// Метод паузы таймера
pause: function() {
if (this.isRunning) {
clearInterval(this.intervalId);
this.isRunning = false;
startButton.disabled = false;
pauseButton.disabled = true;
startButton.textContent = 'Продолжить';
}
},

// Метод сброса таймера
reset: function() {
clearInterval(this.intervalId);
this.isRunning = false;
this.totalSeconds = 0;

// Сбрасываем поля ввода
hoursInput.value = 0;
minutesInput.value = 0;
secondsInput.value = 0;

// Сбрасываем отображение
displayHours.textContent = '00';
displayMinutes.textContent = '00';
displaySeconds.textContent = '00';

// Скрываем уведомление
notification.style.display = 'none';

// Сбрасываем состояние кнопок
startButton.disabled = false;
pauseButton.disabled = true;
startButton.textContent = 'Старт';
},

// Метод обновления времени (вызывается каждую секунду)
tick: function() {
this.totalSeconds -= 1;

if (this.totalSeconds <= 0) {
this.timeUp();
} else {
this.updateDisplay();
}
},

// Метод обновления отображения времени
updateDisplay: function() {
const hours = Math.floor(this.totalSeconds / 3600);
const minutes = Math.floor((this.totalSeconds % 3600) / 60);
const seconds = this.totalSeconds % 60;

displayHours.textContent = this.formatTime(hours);
displayMinutes.textContent = this.formatTime(minutes);
displaySeconds.textContent = this.formatTime(seconds);
},

// Метод форматирования времени (добавление ведущего нуля)
formatTime: function(time) {
return time < 10 ? `0${time}` : time;
},

// Метод, вызываемый по окончании времени
timeUp: function() {
clearInterval(this.intervalId);
this.isRunning = false;
this.totalSeconds = 0;

displayHours.textContent = '00';
displayMinutes.textContent = '00';
displaySeconds.textContent = '00';

notification.style.display = 'block';

startButton.disabled = false;
pauseButton.disabled = true;
startButton.textContent = 'Старт';

// Воспроизведение звукового сигнала
this.playAlarm();
},

// Метод воспроизведения звукового сигнала
playAlarm: function() {
const audio = new Audio('https://assets.mixkit.co/sfx/preview/mixkit-alarm-digital-clock-beep-989.mp3');
audio.play().catch(e => console.log('Автовоспроизведение отключено браузером:', e));
}
};

// Назначаем обработчики событий
startButton.addEventListener('click', () => timer.start());
pauseButton.addEventListener('click', () => timer.pause());
resetButton.addEventListener('click', () => timer.reset());

// Валидация ввода для предотвращения отрицательных значений
function validateInput(input) {
if (input.value < 0) input.value = 0;
if (input.id === 'hours' && input.value > 23) input.value = 23;
if ((input.id === 'minutes' || input.id === 'seconds') && input.value > 59) input.value = 59;
}

hoursInput.addEventListener('change', () => validateInput(hoursInput));
minutesInput.addEventListener('change', () => validateInput(minutesInput));
secondsInput.addEventListener('change', () => validateInput(secondsInput));

Разберем ключевые аспекты нашей JavaScript-реализации:

  1. Структура данных — используем объект timer для хранения состояния и методов таймера
  2. Обработка времени — конвертируем часы, минуты и секунды в общее количество секунд для удобства расчетов
  3. Интервал обновления — используем setInterval для обновления таймера каждую секунду
  4. Валидация ввода — обеспечиваем корректные значения в полях ввода
  5. Отображение — форматируем время с ведущими нулями для единообразия

Особое внимание стоит обратить на обработку состояний таймера. У нас есть три основных состояния:

Состояние Описание Статус кнопок
Не запущен Таймер готов к запуску с новыми значениями Старт: активна, Пауза: неактивна
Работает Таймер ведет обратный отсчет Старт: неактивна, Пауза: активна
Приостановлен Таймер временно остановлен Старт (Продолжить): активна, Пауза: неактивна
Завершен Время истекло Старт: активна, Пауза: неактивна, Отображается уведомление

Мы также добавили метод playAlarm() для воспроизведения звукового сигнала по окончании времени. Обратите внимание на использование .catch() при вызове audio.play() — это необходимо, поскольку многие браузеры блокируют автоматическое воспроизведение звука без явного взаимодействия с пользователем. 🔊

Для предотвращения некорректного ввода мы реализовали функцию validateInput(), которая контролирует допустимые значения для часов (0-23) и минут/секунд (0-59). Это улучшает пользовательский опыт и предотвращает потенциальные ошибки в работе таймера.

Расширение функционала: уведомления и дополнительные режимы

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

Расширим функциональность в следующих направлениях:

  1. Добавим режим Pomodoro с предустановленными интервалами
  2. Реализуем настраиваемые звуковые и визуальные уведомления
  3. Добавим возможность сохранения пользовательских настроек
  4. Интегрируем поддержку Desktop Notifications API

Сначала расширим HTML-структуру, добавив новые элементы интерфейса:

HTML
Скопировать код
<!-- Добавляем после контейнера timer-setup -->
<div class="timer-modes">
<h3>Режимы таймера</h3>
<div class="mode-buttons">
<button id="pomodoro-mode">Pomodoro (25:00)</button>
<button id="short-break">Короткий перерыв (5:00)</button>
<button id="long-break">Длинный перерыв (15:00)</button>
</div>
</div>

<!-- Добавляем после timer-notification -->
<div class="timer-settings">
<h3>Настройки</h3>
<div class="settings-group">
<label for="notification-sound">Звуковое уведомление</label>
<select id="notification-sound">
<option value="beep">Звуковой сигнал</option>
<option value="bell">Колокольчик</option>
<option value="digital">Цифровой</option>
<option value="none">Отключено</option>
</select>
</div>
<div class="settings-group">
<label for="desktop-notifications">Уведомления рабочего стола</label>
<input type="checkbox" id="desktop-notifications">
</div>
<button id="save-settings">Сохранить настройки</button>
</div>

Теперь добавим стили для новых элементов в CSS:

CSS
Скопировать код
/* Стили для режимов таймера */
.timer-modes {
margin: 25px 0;
text-align: center;
}

.timer-modes h3 {
margin-bottom: 15px;
font-size: 18px;
color: #2c3e50;
}

.mode-buttons {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
}

.mode-buttons button {
background-color: #3498db;
color: white;
padding: 8px 15px;
border-radius: 4px;
}

.mode-buttons button:hover {
background-color: #2980b9;
}

/* Стили для настроек */
.timer-settings {
margin-top: 30px;
background-color: #f8f9fa;
padding: 20px;
border-radius: 8px;
}

.timer-settings h3 {
margin-bottom: 15px;
font-size: 18px;
color: #2c3e50;
}

.settings-group {
margin-bottom: 15px;
display: flex;
align-items: center;
justify-content: space-between;
}

.settings-group label {
font-size: 14px;
color: #34495e;
}

.settings-group select,
.settings-group input[type="checkbox"] {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}

#save-settings {
background-color: #9b59b6;
color: white;
width: 100%;
margin-top: 10px;
}

#save-settings:hover {
background-color: #8e44ad;
}

Теперь расширим JavaScript-логику для поддержки новых функций:

JS
Скопировать код
// Получаем ссылки на новые DOM-элементы
const pomodoroButton = document.getElementById('pomodoro-mode');
const shortBreakButton = document.getElementById('short-break');
const longBreakButton = document.getElementById('long-break');
const notificationSound = document.getElementById('notification-sound');
const desktopNotifications = document.getElementById('desktop-notifications');
const saveSettingsButton = document.getElementById('save-settings');

// Расширяем объект timer новыми свойствами и методами
timer.settings = {
sound: 'beep',
desktopNotifications: false,

// Звуки для различных типов уведомлений
sounds: {
beep: 'https://assets.mixkit.co/sfx/preview/mixkit-alarm-digital-clock-beep-989.mp3',
bell: 'https://assets.mixkit.co/sfx/preview/mixkit-classic-alarm-995.mp3',
digital: 'https://assets.mixkit.co/sfx/preview/mixkit-digital-clock-digital-alarm-buzzer-992.mp3'
}
};

// Метод сохранения настроек в localStorage
timer.saveSettings = function() {
this.settings.sound = notificationSound.value;
this.settings.desktopNotifications = desktopNotifications.checked;

localStorage.setItem('timerSettings', JSON.stringify(this.settings));
alert('Настройки сохранены!');
};

// Метод загрузки настроек из localStorage
timer.loadSettings = function() {
const savedSettings = localStorage.getItem('timerSettings');
if (savedSettings) {
this.settings = JSON.parse(savedSettings);
notificationSound.value = this.settings.sound;
desktopNotifications.checked = this.settings.desktopNotifications;
}
};

// Переопределяем метод воспроизведения звука с учетом настроек
timer.playAlarm = function() {
if (this.settings.sound !== 'none') {
const soundUrl = this.settings.sounds[this.settings.sound];
const audio = new Audio(soundUrl);
audio.play().catch(e => console.log('Автовоспроизведение отключено браузером:', e));
}

// Отправляем уведомление рабочего стола, если разрешено
if (this.settings.desktopNotifications && Notification.permission === 'granted') {
new Notification('Таймер завершен!', {
body: 'Ваше установленное время истекло.',
icon: 'https://example.com/timer-icon.png' // Замените на реальный путь к иконке
});
}
};

// Метод установки предустановленного времени
timer.setPresetTime = function(hours, minutes, seconds) {
hoursInput.value = hours;
minutesInput.value = minutes;
secondsInput.value = seconds;

// Сбрасываем текущий таймер, если он запущен
if (this.isRunning) {
this.reset();
}
};

// Добавляем обработчики событий для режимов Pomodoro
pomodoroButton.addEventListener('click', () => timer.setPresetTime(0, 25, 0));
shortBreakButton.addEventListener('click', () => timer.setPresetTime(0, 5, 0));
longBreakButton.addEventListener('click', () => timer.setPresetTime(0, 15, 0));
saveSettingsButton.addEventListener('click', () => timer.saveSettings());

// Запрашиваем разрешение на отправку уведомлений при загрузке страницы
window.addEventListener('load', function() {
timer.loadSettings();

if ('Notification' in window) {
if (Notification.permission !== 'granted' && Notification.permission !== 'denied') {
desktopNotifications.addEventListener('change', function() {
if (this.checked) {
Notification.requestPermission();
}
});
}
} else {
desktopNotifications.disabled = true;
const settingGroup = desktopNotifications.closest('.settings-group');
settingGroup.innerHTML += '<span class="not-supported">Не поддерживается браузером</span>';
}
});

Давайте рассмотрим основные улучшения, которые мы добавили:

  • Режим Pomodoro — предустановленные интервалы для популярной техники управления временем (25 минут работы, 5 минут короткого перерыва, 15 минут длинного перерыва)
  • Настраиваемые звуки — пользователь может выбрать один из предустановленных звуков или отключить звуковые уведомления
  • Desktop Notifications API — позволяет отправлять уведомления на уровне операционной системы, даже если браузер не в фокусе
  • Сохранение настроек — использование localStorage для сохранения пользовательских предпочтений между сессиями

Особое внимание следует обратить на работу с Desktop Notifications API. Для отправки уведомлений на рабочий стол необходимо получить явное разрешение от пользователя, поэтому мы запрашиваем его только при включении соответствующей опции. Также мы добавили проверку поддержки этой функции браузером. ⚠️

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

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

Создание онлайн-таймера — это не просто упражнение в программировании, а путь к пониманию взаимодействия ключевых веб-технологий. Через этот проект вы научились структурировать HTML семантически, создавать отзывчивый дизайн с CSS и программировать интерактивность с JavaScript. Главное — не останавливаться на базовой функциональности. Экспериментируйте с дополнительными фичами: добавьте темы оформления, синхронизацию с календарем или создайте таймер для командной работы. Помните: каждый практический проект — это шаг к мастерству в веб-разработке.

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какой язык разметки используется для создания базовой структуры онлайн-таймера?
1 / 5

Загрузка...