js/a11y.js — fokuso gaudymas
Kodo stulpelyje — js/a11y.js su trapFocus ir hideBackground. Tai — pamokos širdis.
trapFocus(container) daro visus tris dalykus:
- Įveda fokusą (
initialFocus?.focus()) atsidarant. - Sulaiko jį per
Tabklausytoją: suranda pirmą ir paskutinį fokusuojamą elementą;Tabant paskutinio → grįžta į pirmą,Shift+Tabant pirmo → į paskutinį. - Grąžina fokusą: prieš atidarant įsimena
document.activeElement(mygtuką, kuris atidarė), orelease()jį.focus().
export function trapFocus(container, { initialFocus } = {}) {
const previouslyFocused = document.activeElement; // kas atidarė
function onKeydown(e) {
if (e.key !== 'Tab') return;
const f = getFocusable(container);
const first = f[0], last = f[f.length - 1];
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
}
container.addEventListener('keydown', onKeydown);
(initialFocus || getFocusable(container)[0])?.focus(); // (1) įvedam
return function release() {
container.removeEventListener('keydown', onKeydown);
previouslyFocused?.focus(); // (3) grąžinam
};
}
getFocusable filtruoja el.offsetParent !== null — praleidžia paslėptus elementus (paslėptas mygtukas neturi būti fokuso stotelė).
hideBackground(dialog) uždeda aria-hidden="true" visiems body vaikams, išskyrus dialogą, ir grąžina funkciją atstatymui. Taip ekrano skaitytuvas „nemato" fono.
Patarimas. Grąžinamos
release()/restore()funkcijos — švarus modelis:trapFocusirhideBackgroundįjungia elgesį ir grąžina būdą jį atšaukti. Modalas tik iškviečia jas atidarydamas ir jų grąžintas funkcijas — užverdamas. Jokių globalių kintamųjų, jokio „ar dar aktyvu".