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 neperimtumeCtrl+F,Cmd+Rir 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.