Browser API → Объекты документа и страницы → События
Основная идея
DOM-события — это сигналы, которые браузер отправляет при взаимодействии пользователя со страницей или при изменении её состояния. События позволяют JavaScript реагировать на клики, нажатия клавиш, загрузку страницы и многое другое.
Ключевые аспекты
События мыши — click, dblclick, mouseenter, mouseleave, mousemove, mousedown, mouseup
События клавиатуры — keydown, keyup, keypress (устарел)
События форм — submit, change, input, focus, blur
События документа/окна — load, DOMContentLoaded, resize, scroll
События касания (touch) — touchstart, touchmove, touchend
Категории событий
Пользовательские действия — инициируются пользователем (клик, ввод)
Системные события — генерируются браузером (загрузка, ошибки)
Кастомные события — создаются программно через CustomEvent
Плюсы событийной модели
Декларативная реакция на действия пользователя
Отделение логики от представления
Возможность множественных обработчиков на одно событие
Всплытие событий позволяет делегировать обработку
Частые ошибки на собеседованиях
Путают keydown и keypress — keypress устарел и не срабатывает на служебных клавишах
Не знают разницу между mouseenter/mouseleave и mouseover/mouseout (вторые всплывают)
Путают load и DOMContentLoaded — DOMContentLoaded срабатывает раньше, до загрузки картинок и стилей
Забывают про input vs change — input срабатывает при каждом изменении, change — при потере фокуса
Введение и проблематика
Веб-страницы интерактивны — пользователи кликают по кнопкам, вводят текст, скроллят страницу. Браузер должен каким-то образом сообщать JavaScript о всех этих действиях. Для этого существует событийная модель DOM.
События — это сигналы от браузера о том, что что-то произошло. JavaScript может "подписаться" на эти сигналы и выполнить код в ответ.
Зачем нужны события?
Без событий веб-страницы были бы статичными. События позволяют:
Реагировать на клики по кнопкам
Валидировать формы при отправке
Создавать drag-and-drop интерфейсы
Реализовывать горячие клавиши
Делать infinite scroll
И многое другое
Базовая теория
Что такое DOM-событие
Событие (Event) — это объект, который создаётся браузером при определённых действиях и содержит информацию о том, что произошло:
js
element.addEventListener('click',function(event) {console.log(event.type); // "click"console.log(event.target); // элемент, на котором произошёл кликconsole.log(event.clientX); // координата X курсораconsole.log(event.clientY); // координата Y курсора});
Классификация событий
События можно разделить на несколько категорий:
graphTB A[DOM Events]--> B[Mouse Events] A --> C[Keyboard Events] A --> D[Form Events] A --> E[Document Events] A --> F[Touch Events] A --> G[Other Events] B --> B1[click, dblclick] B --> B2[mouseenter, mouseleave] B --> B3[mousemove, mousedown, mouseup] C --> C1[keydown, keyup] D --> D1[submit, reset] D --> D2[focus, blur] D --> D3[input, change] E --> E1[DOMContentLoaded] E --> E2[load, unload] F --> F1[touchstart, touchmove, touchend]
События мыши
Базовые события клика
Событие
Когда срабатывает
click
При клике (нажатие + отпускание)
dblclick
При двойном клике
mousedown
При нажатии кнопки мыши
mouseup
При отпускании кнопки мыши
contextmenu
При клике правой кнопкой (контекстное меню)
js
constbutton=document.querySelector('button');button.addEventListener('click', () => {console.log('Клик!');});button.addEventListener('dblclick', () => {console.log('Двойной клик!');});// Порядок событий при клике: mousedown → mouseup → clickbutton.addEventListener('mousedown', () =>console.log('1. mousedown'));button.addEventListener('mouseup', () =>console.log('2. mouseup'));button.addEventListener('click', () =>console.log('3. click'));
События наведения
js
// НЕ всплывают, срабатывают только на целевом элементеconstcard=document.querySelector('.card');card.addEventListener('mouseenter', () => {card.classList.add('hovered');console.log('Курсор вошёл в card');});card.addEventListener('mouseleave', () => {card.classList.remove('hovered');console.log('Курсор покинул card');});
⚠️
Используйте mouseenter/mouseleave когда вам нужно отслеживать вход/выход только из самого элемента. mouseover/mouseout полезны для делегирования событий.
Событие движения мыши
js
document.addEventListener('mousemove', (e) => {// Координаты относительно viewportconsole.log(`Viewport: ${e.clientX}, ${e.clientY}`);// Координаты относительно документа (с учётом скролла)console.log(`Document: ${e.pageX}, ${e.pageY}`);// Координаты относительно экранаconsole.log(`Screen: ${e.screenX}, ${e.screenY}`);});
// DOM готов (HTML распарсен), но картинки/стили могут ещё загружатьсяdocument.addEventListener('DOMContentLoaded', () => {console.log('DOM готов');initializeApp();});// Вся страница загружена (включая картинки, стили, iframe)window.addEventListener('load', () => {console.log('Страница полностью загружена');hideLoader();});// Пользователь покидает страницуwindow.addEventListener('beforeunload', (e) => {if (hasUnsavedChanges) {e.preventDefault();e.returnValue =''; // Показать диалог подтверждения }});
⚠️
Всегда используйте DOMContentLoaded вместо load если вам нужно только работать с DOM. load ждёт загрузки всех ресурсов, что может быть долго.