Мышь, клавиатура, pointer

Мышь, клавиатура, pointer #

События ввода переводят действия пользователя в вызовы JavaScript. Мышь и pointer покрывают указатель и тач; клавиатура — фокус и shortcuts. В JSFlow они управляют плеером, перетаскиванием виджетов дашборда и навигацией по checkout без лишних кликов.


Мышь: основные типы #

СобытиеКогда срабатывает
clickполный цикл нажатия и отпускания на том же элементе
dblclickдвойной клик
mousedown / mouseupнажатие / отпускание кнопки
mousemoveдвижение с зажатой или без кнопки
mouseenter / mouseleaveкурсор вошёл / вышел из элемента (не всплывают)
contextmenuправый клик
const volumeSlider = document.querySelector('.player__volume')

volumeSlider.addEventListener('click', (event) => {
  const rect = volumeSlider.getBoundingClientRect()
  const ratio = (event.clientX - rect.left) / rect.width
  setVolume(Math.min(1, Math.max(0, ratio)))
})

clientX / clientY — координаты относительно viewport; pageX / pageY учитывают прокрутку документа.


Pointer Events #

Pointer Events унифицируют мышь, перо и touch одним API:

const handle = document.querySelector('.widget__drag-handle')

handle.addEventListener('pointerdown', (event) => {
  handle.setPointerCapture(event.pointerId)
  startWidgetDrag(event.clientX, event.clientY)
})

handle.addEventListener('pointermove', (event) => {
  if (!handle.hasPointerCapture(event.pointerId)) return
  moveWidgetDrag(event.clientX, event.clientY)
})

handle.addEventListener('pointerup', (event) => {
  handle.releasePointerCapture(event.pointerId)
  endWidgetDrag()
})

setPointerCapture направляет последующие события указателя на элемент, даже если палец или курсор ушёл за его границы.


Клавиатура: keydown и keyup #

document.addEventListener('keydown', (event) => {
  if (event.target.matches('input, textarea, select')) return

  if (event.code === 'Space') {
    event.preventDefault()
    togglePlayback()
  }

  if (event.key === 'ArrowRight' && event.altKey) {
    skipToNextTrack()
  }
})
СвойствоСмысл
keyсимвол или имя клавиши ("Enter", "а")
codeфизическая клавиша ("KeyK", "Space")
ctrlKey, shiftKey, altKey, metaKeyмодификаторы
repeatзажатие — повторные keydown

Для глобальных shortcuts игнорируйте ввод, когда фокус в поле формы checkout.


focus и ввод текста #

const search = document.querySelector('.playlist-search')

search.addEventListener('input', (event) => {
  filterTracks(event.target.value.trim())
})

search.addEventListener('keydown', (event) => {
  if (event.key === 'Escape') {
    event.target.value = ''
    filterTracks('')
    event.target.blur()
  }
})

input срабатывает при каждом изменении значения; change — при commit (blur или Enter у некоторых контролов).


Комбинация: seek по клику и drag #

const progress = document.querySelector('.player__progress')
let dragging = false

progress.addEventListener('pointerdown', (event) => {
  dragging = true
  progress.setPointerCapture(event.pointerId)
  seekByClientX(event.clientX)
})

progress.addEventListener('pointermove', (event) => {
  if (!dragging) return
  seekByClientX(event.clientX)
})

progress.addEventListener('pointerup', () => {
  dragging = false
})

function seekByClientX(clientX) {
  const rect = progress.getBoundingClientRect()
  const pct = (clientX - rect.left) / rect.width
  seekToPercent(pct)
}

Итог #

  • click и координаты clientX/Y — hit-testing по полосе прогресса и слайдерам.
  • Pointer Events + setPointerCapture — надёжный drag на touch и mouse.
  • keydown: проверяйте event.key / code, модификаторы и repeat.
  • Фильтруйте глобальные hotkeys, когда фокус в полях формы.

См. также #