Poslepu.cz na novém URL

Od ledna 2014 najdete blog na adrese poslepu.cz.

neděle 3. ledna 2010

Tajemství fokusu

Už před nějakou dobou jsme s kolegy řešili případ rozhraní ke skeneru, které při zahájení snímání porušilo kontinuitu předávání fokusu a uvedlo uživatele do stavu, kdy nebylo žádné okno aktivní. Místo toho, abychom klientům vysvětlovali, k jaké nestandardní situaci došlo, zvolili jsme pro skener raději jiné rozhraní. Zatímco uvedení fokusu do nedefinovatelného stavu je v prostředí operačního systému věc spíše výjimečná, ve webových aplikacích s masivním nasazením Javascriptu k tomuto jevu dochází celkem běžně. Častá ztráta fokusu pak být jeden z hlavních faktorů, proč nebudou uživatelé rozhraní webové aplikace považovat za ideálně přístupné.

Fokus v operačním systému

V operačním systému při spuštění aplikace či při vyvolání nového modálního dialogu získá okno fokus a zároveň první ovládací prvek v něm. Odečítač obrazovky tuto skutečnost komentuje tím, že přečte titulkový pruh aplikace/dialogu a pokračuje oznámením aktuálního ovládacího prvku, čímž uživatel má bod, z něhož může vyjít. Je-li okno zavřeno, je v případě zavřené aplikace fokus předán naposledy použité aplikaci a to ovládacímu prvku, jenž v ní byl naposledy aktivní, v případě modálního dialogu je fokus předán do nadřazeného okna tak, že nejčastěji se uživatel ocitá na ovládacím prvku, jenž modální dialog vyvolal. Abychom přesněji pochopili, o co se jedná, představme si případ, kdy chceme projít do a z dialogu Rozšířené nastavení Javascriptu v prohlížeči Mozilla Firefox:

  1. Aktivní okno aktuální záložky s webovou stránkou a nějaký odkaz v něm
  2. Zvolíme z aplikačního menu Nástroje / Možnosti - aktivní okno Možnosti, ovládací prvek seznam karet dialogu
  3. Přejdeme na kartu Obsah a na ní na tlačítko Rozšířené - aktivní okno Možnosti, karta Obsah, ovládací prvek Rozšířené (tlačítko)
  4. Aktivujeme tlačítko - aktivní okno Rozšířené nastavení Javascriptu, ovládací prvek Přemisťovat nebo měnit velikost okna (zaškrtávací políčko)
  5. Aktivujeme tlačítko Zrušit - aktivní okno Možnosti, karta Obsah, ovládací prvek Rozšířené (tlačítko)
  6. Aktivujeme tlačítko Zrušit - aktivní okno aktuální záložky s webovou stránkou a nějaký odkaz v něm

Vidíme, že poloha fokusu je vždy jednoznačně definována a uchovávána i pro na sebe vrstvené modální dialogy. Toto chování je zcela v režii grafického uživatelského rozhraní operačního systému a není ovlivňováno tvůrcem aplikace.

Fokus ve webové aplikaci

Ve webové aplikaci vyvolání modálního dialogu nejčastěji znamená, že aktivováním odkazu/tlačítka se na konec stránky vloží nový kód představující dialog a příslušně se nastyluje, aby vystoupil do popředí. Vizuálně je vše v pořádku, fokus však v ideálním případě zůstává na ovládacím prvku, který dialog vyvolal, neboť webový prohlížeč neví, zda uživatel si přeje vstoupit na některý z fokusovatelných elementů v nově se objevivším obsahu - co když jde jen o reklamní sdělení?

Komplikovanější situace nastává ve chvíli, kdy se nacházíme uvnitř dialogu webové aplikace a ten chceme zavřít. Po aktivaci příslušného odkazu/tlačítka je obsah ze stránky sice odstraněn, ale rovněž i ovládací prvek mající fokus. Protože prohlížeč opět neví, kam fokus předat, skončí stránka v nejednoznačném stavu, kdy fokus získá to, co je, tak říkajíc, nejblíže po ruce.

Právě tyto popsané nejednoznačnosti uživatelům odečítačů působí problémy, neboť správné směrování fokusu přispívá k zorientování se v prostředí. Pro takového uživatele je fokus středobodem všeho, neboť ve většině situací skrze odečítač není schopen vnímat dění na obrazovce v širších souvislostech. Ne nadarmo základní nastavení odečítače je takové, že je čteno jen to, co má fokus, protože při zvolení jiné strategie je uživatel často zahlcen informacemi o zcela nepodstatných změnách na obrazovce.

Zkrocení fokusu

První krok, který nás nic nestojí, neboť nevyžaduje zásah do funkcí v Javascriptu, je označení oblastí stránky, jež se chovají jako dialog, pomocí ARIA role Dialog. Prohlížeč podporující ARIA tak může provést změnu fokusu, která je relevantní k dění na obrazovce a odečítač podporující ARIA může oznámit jméno zobrazeného dialogu, jenž je nejčastěji ukryto v atributu title elementu označeného jako dialog. Fakt je ovšem ten, že drtivé většině uživatelů toto řešení vzhledem k používaným verzím odečítačů a prohlížečů vůbec nepomůže, nehledě na to, že se tím nevyřeší ztráta fokusu při zavírání dialogu.

Aby vše tedy pracovalo tak, jak bylo popsáno výše pro desktopové aplikace, je třeba již zásah do kódu v Javascriptu, který na druhou stranu není nijak drastický:

  1. Element aktivující dialog musí říct dialogu, kdo jej aktivoval.
  2. Dialog se postará o přemístění fokusu na první fokusovatelný element v něm.
  3. Dialog před odstraněním svého obsahu ze stránky přemístí fokus zpět na element, jenž jej vyvolal.

Fokus na webu jako na desktopu

Aby byly přetaveny zmíněné tři body do praxe, implementoval jsem je do diskuzního fóra, kde klikáním na odkazy Odpovědět a v zápětí na tlačítko Storno u jednotlivých příspěvků můžete sledovat, co se s fokusem děje. Konkrétně veškeré kouzlení v této oblasti má na starost funkce toggleForumApp() v knihovně funkcí, které se jako parametry předávají název hlavní oblasti fóra, název oblasti dialogu a objekt odkazu, který dialog vyvolává. Za zapamatování odkazu, jenž dialog vyvolal má zodpovědnost řádek:

if (typeof(appFocus)!="undefined")
$(appMain).data("appFocus",appFocus);

A za návrat fokusu na původní místo před zavřením dialogu tento kód:


if (typeof($(appMain).data("appFocus"))!="undefined")
{
$(appMain).data("appFocus").focus();
$(appMain).removeData("appFocus");
}

Kód je psán za mohutného přispění knihovny JQuery, tudíž případné nejasnosti konzultujte v její nápovědě.

Autorem článku je Roman Kabelka.

1 komentář:

Libor řekl(a)...

Zajímavý článek, ovšem následující tvrzení není pravdivé:

"Toto chování je zcela v režii grafického uživatelského rozhraní operačního systému a není ovlivňováno tvůrcem aplikace."