Fresh — это современный подход к разработке веб-приложений, обеспечивающий эффективное управление состоянием и реактивностью интерфейса без необходимости использования сложных фреймворков. Ключевая идея заключается в том, чтобы каждая часть приложения могла быть обновлена независимо и предсказуемо, а изменения состояния автоматически отражались в интерфейсе.
В JavaScript обработчики событий позволяют реагировать на действия пользователя, такие как клики, наведение мыши, ввод текста или отправка формы. Одним из важных аспектов является возможность назначения нескольких обработчиков на один элемент и контроль их поведения.
Для одного DOM-элемента можно назначить несколько функций на
одно событие. Это делается с помощью метода
addEventListener. В отличие от свойства
onclick, которое поддерживает только один обработчик,
addEventListener позволяет добавлять неограниченное
количество функций, которые будут вызваны в порядке их
регистрации.
const button = document.querySelector('#myButton');
button.addEventListener('click', () => console.log('Первый обработчик'));
button.addEventListener('click', () => console.log('Второй обработчик'));
При клике на кнопку будут последовательно выполнены оба обработчика. Порядок выполнения соответствует порядку их регистрации.
Каждый обработчик, зарегистрированный через
addEventListener, можно удалить с помощью
removeEventListener. Для этого необходима ссылка на
исходную функцию, что делает анонимные функции неудобными для
удаления.
function handleClick() {
console.log('Обработчик для удаления');
}
button.addEventListener('click', handleClick);
// Позже
button.removeEventListener('click', handleClick);
Удаление анонимного обработчика невозможно, так как ссылка на функцию отсутствует.
once и управление повторным вызовомПри регистрации обработчиков через addEventListener
можно использовать опцию once, чтобы обработчик
сработал только один раз и автоматически удалился после
выполнения:
button.addEventListener('click', () => console.log('Сработает один раз'), { once: true });
Это удобно для событий, которые должны реагировать на одно действие пользователя, например, первичное подтверждение.
Все обработчики, назначенные на одно событие, вызываются в
том порядке, в котором они были зарегистрированы. Однако важно
учитывать фазу события: захват (capture)
или всплытие (bubble). По умолчанию используется фаза
всплытия.
document.querySelector('#parent').addEventListener(
'click',
() => console.log('Родитель (bubble)'),
false
);
document.querySelector('#parent').addEventListener(
'click',
() => console.log('Родитель (capture)'),
true
);
Обработчик с capture: true сработает до
обработчиков фазы всплытия, даже если они были зарегистрированы
раньше.
В контексте Fresh множественные обработчики часто используются для разделения логики интерфейса и состояния. Один обработчик может управлять визуальными эффектами, другой — обновлять состояние приложения или вызывать серверные запросы. Такой подход облегчает тестирование и поддержку кода:
const state = { count: 0 };
button.addEventListener('click', () => state.count++);
button.addEventListener('click', () => console.log(`Новое значение: ${state.count}`));
Каждая функция выполняет отдельную задачу, при этом не мешает другой, что соответствует принципам реактивной архитектуры Fresh.
Для динамически создаваемых элементов важно использовать делегирование событий, когда обработчик назначается на родительский элемент и фильтрует события по целевому элементу. Это позволяет управлять множественными событиями через один обработчик, сохраняя производительность и чистоту кода:
document.querySelector('#list').addEventListener('click', (event) => {
if (event.target.tagName === 'LI') {
console.log(`Клик по элементу списка: ${event.target.textContent}`);
}
});
Даже если элементы будут добавляться динамически, обработчик останется актуальным.
addEventListener вместо
onclick для поддержки нескольких обработчиков.once для одноразовых событий.Множественные обработчики в сочетании с реактивными принципами Fresh позволяют создавать чистые, масштабируемые и предсказуемые интерфейсы, где каждая часть приложения отвечает только за свою функциональность, а изменения состояния автоматически отражаются в представлении.