Tema
/
Interneto svetainių kliento dalies kūrimas JS

js/shortcuts.js — vienas klausytojas visiems klavišams

Kodo stulpelyje — js/shortcuts.js. Tai idealus delegavimo pavyzdys: vienas klausytojas ant document aptarnauja visus klaviatūros klavišus. Nekabinam po klausytoją kiekvienam klavišui — leidžiam įvykiams suburbuliuoti iki document ir ten nusprendžiam, ką daryti.

Kaip veikia: register('g', () => navigate('/gallery')) įsimena klavišą; initShortcuts() klausosi keydown ant document ir, radęs atitikmenį, iškviečia veiksmą.

Du sprendimai čia svarbūs (ir abu — realaus UX klausimai):

  • Nevogti klavišų, kai vartotojas rašo. isTyping(e.target) patikrina, ar fokusas įvesties laukelyje. Jei taip — praleidžiam (kad / paieškos laukelyje įrašytų pasvirą brūkšnį, o ne atidarytų paiešką). Išimtis — Escape, kuris visada turi „išeiti".
  • Nesikauti su naršykle. Jei paspaustas Ctrl/Cmd/Alt — praleidžiam, kad neperimtume Ctrl+F, Cmd+R ir pan.
document.addEventListener('keydown', (e) => {
  if (isTyping(e.target)) { if (e.key === 'Escape') e.target.blur(); return; }
  if (e.metaKey || e.ctrlKey || e.altKey) return;
  const entry = shortcuts.get(e.key.toLowerCase());
  if (entry) { e.preventDefault(); entry.handler(e); }
});

Pastebėk e.preventDefault() — kai klavišas mūsų, sustabdom naršyklės numatytąjį veiksmą, kad, tarkim, / neatidarytų naršyklės paieškos.

Patarimas. Šis modelis — „vienas klausytojas, žemėlapis veiksmų" — kartojasi visur: klaviatūra, sąrašų paspaudimai, meniu. Užuot pridėję N klausytojų (ir juos valę), pridedi vieną prie tėvo. Mažiau kodo, mažiau nutekėjimų (memory leaks), veikia ir dinamiškai atsiradusiam turiniui.