Клавиатура и мышь
События клавиатуры
keydown— нажатиеkeyup— отпускание
document.addEventListener('keydown', (event) => {
console.log(event.key); // 'a', 'Enter', 'Escape'
console.log(event.code); // 'KeyA', 'Enter', 'Escape'
});
key vs code
- key — символ с учётом раскладки
- code — физическая клавиша
// Русская раскладка
event.key; // 'ф' (или 'a' на английской)
event.code; // 'KeyA' — всегда
Для горячих клавиш используй code — не зависит от раскладки.
Модификаторы
if (event.ctrlKey && event.key === 's') {
event.preventDefault();
save();
}
if (event.metaKey && event.key === 'k') {
openSearch(); // Cmd+K на Mac
}
if (event.shiftKey && event.key === 'Enter') {}
if (event.altKey) {}
На Mac Ctrl — это metaKey.
Escape и Enter
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') closeModal();
if (event.key === 'Enter') submit();
});
Ограничение ввода
input.addEventListener('keydown', (event) => {
if (!/^[0-9]$/.test(event.key) && event.key !== 'Backspace' && event.key !== 'Tab') {
event.preventDefault();
}
});
События мыши
click— кликdblclick— двойнойmousedown,mouseup— нажатие/отпусканиеmousemove— движениеmouseover,mouseout— вход/выход (всплывают)mouseenter,mouseleave— вход/выход (не всплывают)contextmenu— правый клик
Координаты
element.addEventListener('click', (event) => {
event.clientX; // относительно окна
event.clientY;
event.pageX; // относительно документа (с прокруткой)
event.pageY;
event.offsetX; // относительно элемента
event.offsetY;
});
Кнопки мыши
element.addEventListener('mousedown', (event) => {
event.button; // 0 — левая, 1 — средняя, 2 — правая
});
Правый клик
document.addEventListener('contextmenu', (event) => {
event.preventDefault();
showCustomMenu(event.pageX, event.pageY);
});
mouseover vs mouseenter
// mouseover срабатывает при переходе на дочерние
parent.addEventListener('mouseover', () => console.log('over'));
// mouseenter — только при входе в сам элемент
parent.addEventListener('mouseenter', () => console.log('enter'));
mouseenter обычно нужен.
Drag and drop
draggable.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'data');
event.dataTransfer.effectAllowed = 'move';
});
dropZone.addEventListener('dragover', (event) => {
event.preventDefault(); // обязательно
});
dropZone.addEventListener('drop', (event) => {
event.preventDefault();
const data = event.dataTransfer.getData('text/plain');
});
Pointer events
Современная альтернатива — мышь, касания, перо:
element.addEventListener('pointerdown', (event) => {});
element.addEventListener('pointermove', (event) => {});
element.addEventListener('pointerup', (event) => {});
Один API для всех устройств.
Touch
element.addEventListener('touchstart', (event) => {
const touch = event.touches[0];
console.log(touch.clientX, touch.clientY);
});
Практика: горячие клавиши
const shortcuts = {
'ctrl+s': () => save(),
'ctrl+z': () => undo(),
'ctrl+shift+z': () => redo(),
};
document.addEventListener('keydown', (event) => {
const parts = [];
if (event.ctrlKey || event.metaKey) parts.push('ctrl');
if (event.shiftKey) parts.push('shift');
if (event.altKey) parts.push('alt');
parts.push(event.key.toLowerCase());
const combo = parts.join('+');
if (shortcuts[combo]) {
event.preventDefault();
shortcuts[combo]();
}
});
Итоги
keydown,keyupдля клавиатурыkey— символ,code— физическая клавиша- Модификаторы:
ctrlKey,shiftKey,altKey,metaKey mouseenter/mouseleaveне всплывают- Pointer events — единый API
- Горячие клавиши через комбинации