Wejście do smoka (zrzut): Zmiana kolejności list z ułatwieniami dostępu
Opublikowany: 2022-03-10Przez lata bycia programistą stron internetowych skupiającym się na dostępności, zajmowałem się głównie szeroko stosowanymi, ustandaryzowanymi komponentami interfejsu użytkownika, dobrze wspieranymi przez technologie wspomagające (AT). W przypadku tego typu widżetów istnieją zwięzłe praktyki tworzenia ARIA, a także świetne narzędzia, takie jak axe-core, które można wykorzystać do testowania komponentów internetowych pod kątem problemów z dostępnością. Tworzenie mniej popularnych widżetów, zwłaszcza tych, które nie mają powszechnie przyjętych konwencji interakcji z użytkownikiem, może być bardzo trudne.
Jednym z najtrudniejszych wyzwań, z jakimi się spotkałem, jest lista przeciągania i upuszczania z możliwością zmiany kolejności. Chociaż lista z możliwością zmiany kolejności jest dość często używanym widżetem z intuicyjnymi konwencjami dla użytkowników myszy, nie jest jasne, w jaki sposób użytkownicy technologii wspomagającej wyłącznie za pomocą klawiatury mogą wykonać to proste zadanie. Ze względu na brak obsługiwanych atrybutów ARIA, Dragon Drop wykorzystuje żywe regiony do przekazywania informacji potrzebnych wszystkim użytkownikom do zmiany kolejności listy.
Regiony na żywo
Aktywne regiony to elementy HTML wyposażone w atrybuty ARIA, których można używać do powiadamiania czytników ekranu o zmianach zawartości. Pozwalają nam dostarczać całkowicie spersonalizowane ogłoszenie czytnika ekranu bez konieczności przesuwania fokusa! Aktywne regiony doskonale nadają się do aktualizacji w czasie rzeczywistym w odległych częściach strony, aktualizacji statusu i informacji wrażliwych na czas.
Są one powszechnie używane w dziennikach czatów, wskaźnikach postępu, aktualizacjach wyników sportowych i alertach pogodowych, ale należy ich używać oszczędnie, ponieważ mogą łatwo stworzyć zbyt rozbudowane środowisko dla użytkowników czytników ekranu. Jeśli jesteś nowy w żywych regionach lub po prostu chcesz odkryć, co mogą zrobić, sprawdź mój plac zabaw na żywo, który pozwala skonfigurować własny niestandardowy region na żywo.
Jeśli chcesz używać regionów na żywo w swojej aplikacji, zapoznaj się z modułem regionów na żywo w npm.
<div aria-live="assertive" role="log" aria-relevant="additions" aria-atomic="true"></div>
Dlaczego warto korzystać z żywych regionów?
W idealnym świecie mógłbym po prostu polegać na atrybutach ARIA typu „przeciągnij i upuść aria-grabbed
-grabbed i aria-dropeffect
. Jednak w rzeczywistości obsługa tych atrybutów jest rzadka, a jeśli jest obsługiwana, jest to mylące i sprzeczne z intuicją dla użytkowników czytników ekranu. Co więcej, te dwa atrybuty zostały wycofane z wersji ARIA 1.1, co oznacza, że w przyszłości nie zaobserwujemy wzrostu obsługi tych atrybutów.
Rozmowę W3C na temat tej deprecjacji można znaleźć tutaj. Z powodu tych problemów zdecydowałem się nie używać w Dragon Drop efektu aria-grabbed
-gragged i aria-dropeffect
. Różnice w obsłudze atrybutów ARIA w ramach szerokiej gamy par technologii wspomagających/przeglądarki są dość powszechne w świecie dostępności. Na szczęście atrybuty aktywnego regionu, takie jak role
, aria-live
, aria-relevant
i aria-atomic
są dość szeroko obsługiwane przez czytniki ekranu, takie jak JAWS, NVDA i VoiceOver.
Zoptymalizowana dostępność
Dragon Drop to wysoce konfigurowalny moduł zmiany kolejności list, który działa dla użytkowników myszy, klawiatury i technologii pomocniczych. Kilka lat temu, kiedy zdecydowałem się to napisać, w projektach, nad którymi pracowałem, kilkakrotnie pojawiały się listy uporządkowania w przystępny sposób, ale nie widziałem jeszcze działającego rozwiązania. Z dziesiątek wtyczek do zmiany kolejności list przeciąganych i upuszczanych, z którymi się zetknąłem, większość z nich nie została zaprojektowana z myślą o dostępności i w rezultacie była bardzo niedostępna.
Dragon Drop został przetestowany z VoiceOver, JAWS i NVDA i umożliwia użytkownikom AT pomyślną zmianę kolejności listy.
Postanowiłem odpowiedzieć na wszystkie pytania, które każdy użytkownik może mieć, gdy napotka listę, którą można zmienić. Odpowiedzi na te pytania dla widzących użytkowników myszy uzyskano za pomocą typowych konwencji, ale co z resztą użytkowników?
Jak mogę odebrać przedmiot?
Dostarczając kontrolkę, która przekazuje stan uchwycenia elementu, wraz z tekstem pomocy najwyższego poziomu, możemy odpowiedzieć na to pytanie. Na przykład kontrolka z dostępnym tekstem (zebrana przez AT, chociaż ma nazwę, rolę i wartość) „Zmień kolejność elementu 1, przycisk przełączania” informuje użytkownika, że jest to przycisk, który po aktywacji podniesie element i uruchomi zmiana kolejności.
Dragon drop używa atrybutu aria-pressed
aby użytkownicy AT wiedzieli, kiedy przedmiot jest „przeciągany”, a kiedy nie. Można go skonfigurować tak, aby umożliwić przeciąganie całego elementu lub tylko podrzędnego „uchwytu przeciągania”, co w obu przypadkach zapewnia obecność role="button"
i tabindex="0"
.
Gdy element przeciągany jest aktywowany, aria-pressed="true"
jest stosowany do elementu, a konfigurowalne ogłoszenie, takie jak „Przechwycony element 1” , jest odczytywane czytnikom ekranu za pośrednictwem aktywnego regionu.
Jak mogę przenieść przedmiot?
Wykorzystanie aria-describedby
do powiązania kontrolek z przydatnym tekstem pomocy, takim jak „Aktywuj przycisk zmiany kolejności i użyj klawiszy strzałek, aby zmienić kolejność listy lub użyj myszy, aby przeciągnąć/zmienić kolejność”. mówi użytkownikowi, jak faktycznie zmienić kolejność. Dzięki temu użytkownicy czytników ekranu wiedzą, że po naciśnięciu elementu klawisze strzałek w górę i w dół przeniosą element odpowiednio w górę iw dół listy.
Jak mogę upuścić przedmiot?
Ponieważ używany jest atrybut aria-pressed
, użytkownicy mogą łatwo powiedzieć, jak upuścić element. W pewien sposób, kształt lub forma, wszystkie najczęściej używane czytniki ekranu przekazują stan naciśnięcia przycisku przełączania. Atrybut aria-wciśnięty jest ustawiany na „false”, gdy element jest upuszczany, a dostosowane komunikaty, takie jak „Upuszczony element 1” , są odczytywane przez czytniki ekranu.
Skąd mam wiedzieć, kiedy lista została zmieniona?
Za każdym razem, gdy klawisze strzałek w górę i w dół są używane do zmiany kolejności listy, musimy upewnić się, że wszyscy użytkownicy zostaną powiadomieni o tej zmianie. W przypadku niewidzących użytkowników ponownie musimy polegać na żywych regionach. Konfigurowalne ogłoszenie, takie jak „Lista została zmieniona, pozycja 1 jest teraz 4. na liście”. , jest odczytywany w celu przekazania zaktualizowanego stanu listy o zmienionej kolejności. Jest to ważne, ponieważ widzący użytkownicy otrzymują natychmiastową wizualną informację zwrotną o zmienionej kolejności i tę samą informację należy przekazać użytkownikom AT.
Jak anulować zmianę kolejności?
Ponieważ nie możemy polegać na powszechnie przyjętej konwencji w przypadku takiej interakcji, możemy po prostu umieścić w tekście pomocy wskazówki, takie jak „Naciśnij klawisz Escape, aby anulować zmianę kolejności” . Ponadto wykorzystujemy region na żywo, aby zapewnić spersonalizowany odczyt, który powiadamia użytkownika o anulowaniu.
Interakcja z klawiaturą
Klucz | Zachowanie |
---|---|
Enter lub spacja | Przełącza element między stanem „złapany” i „upuszczony” |
„↓” | Przesuwa „złapany” element w dół listy |
„↑” | Przenosi „złapany” element w górę listy |
wyjście | Anuluje ponowne zamawianie i przywraca początkowe zamówienie |
Widząc smoka w akcji
Sprawdź demo Dragon Drop, w którym doświadczysz kilku różnych konfiguracji.
Upuszczanie Dragon Drop do Twojej aplikacji
Dragon Drop konwertuje zwykłą listę na w pełni dostępną listę, którą można zmieniać za pomocą przeciągania i upuszczania:
<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul> <script> const dragon = document.getElementById('dragon'); // Enter the dragon new DragonDrop(dragon); </script>
Instalacja
Dragon Drop jest projektem open source (licencja MIT) i można go zainstalować za pośrednictwem npm:
$ npm install drag-on-drop
Może być używany z modułami takimi jak browserify lub webpack:
// if you're not down with ES6, you can require('drag-on-drop') import DragonDrop from 'drag-on-drop';
Dragon Drop można również łatwo upuścić na twoją stronę za pomocą unpkg CDN:
<script source="https://unpkg.com/drag-on-drop"></script> <script> var dragonDrop = new DragonDrop(listElement); </script>
Konfiguracja
Aby obsługiwać szeroki zakres zastosowań, Dragon Drop jest bardzo konfigurowalny.
Poniżej znajduje się domyślna konfiguracja:
{ item: 'li', handle: 'button', activeClass: 'dragon-active', inactiveClass: 'dragon-inactive', announcement: { grabbed: el => `Item ${el.innerText} grabbed`, dropped: el => `Item ${el.innerText} dropped`, reorder: (el, items) => { const pos = items.indexOf(el) + 1; const text = el.innerText; return `The list has been reordered, ${text} is now item ${pos} of ${items.length}`; }, cancel: 'Reordering cancelled' } }
Ogłoszenia
Opcja konfiguracji „ogłoszenia” w Dragon Drop jest najważniejsza, ponieważ stanowi podstawę obsługi czytnika ekranu, którą zapewnia Dragon Drop. Jest to obiekt zawierający funkcje „przechwycone "grabbed"
, "dropped"
, "reorder"
i "cancel"
, pozwalające na niestandardowe ogłoszenia regionu na żywo dla wszystkich interakcji, które mają miejsce.
Każda z tych funkcji musi zwrócić ciąg tekstu ogłoszenia, który jest dodawany do regionu na żywo, gdy dana akcja zostanie wykonana. Dodatkową korzyścią płynącą z korzystania z tych funkcji jest obsługa lokalizacji komunikatów regionu na żywo.
Aby ułatwić zapowiedzi, jako argumenty przekazywane są odpowiednio element listy, na którym miała miejsce akcja, oraz tablica elementów listy.
{ announcement: { // grabbed is called when an item is picked up grabbed: (targetItem, items) => `${targetItem.innerText} grabbed`, // dropped is called when an item is dropped dropped: (targetItem, items) => `${targetItem.innerText} grabbed`, // reorder is called each time the order of the list is altered reorder: (targetItem, items) => { return `${targetItem.innerText} is now ${items.indexOf(targetItem) + 1} of ${items.length}` }, // cancel is called when a reordering is cancelled (via escape key) cancel: () => 'The initial order has been restored, reordering cancelled' } }
Tekst pomocy
Niezbędne jest dostarczenie tekstu pomocy, który opisuje, jak korzystać z listy do zmiany kolejności. To jest coś, czego Dragon Drop nie robi dla ciebie, aby pozostać mniej zdecydowanym w kwestii tego, jak ten tekst jest udostępniany technologii wspomagającej. Zalecaną implementacją jest użycie aria-describedby
do powiązania tekstu pomocy z elementami interaktywnymi, jak na przykład:
<p>Activate the reorder button and use the arrow keys to reorder the list or use your mouse to drag/reorder. Press escape to cancel the reordering.</p> <ul> <li> <button>Reorder Item 1</button> <span>Item 1</span> </li> <li> <button>Reorder Item 2</button> <span>Item 2</span> </li> <li> <button>Reorder Item 3</button> <span>Item 3</span> </li> </ul>
Dragon Drop na GitHub
Niedawno ukazała się trzecia wersja Dragon Drop. Jeśli jesteś zainteresowany jego użyciem, zapoznaj się z dokumentacją Dragon Drop na GitHub. Specjalne podziękowania należą się twórcom Draguli, modułu, którego Dragon Drop używa do interakcji myszy, a także Aarona Pearlmana, który zaprojektował niesamowite logo!
Przyszłość smoka
Jeśli w przyszłości do specyfikacji technicznej WAI-ARIA zostanie dodana interakcja „przeciągnij i upuść”, fakt, że Dragon Drop opiera się na niestandardowej interakcji, a aktywne regiony może ulec zmianie. Będę kontynuował testy, aby upewnić się, że jest dobrze obsługiwany przez jak najwięcej czytników ekranu i będę na bieżąco z najnowszą specyfikacją ARIA. Ponadto w przygotowaniu jest sporo funkcji, w tym obsługa ekranów dotykowych/urządzeń mobilnych, a także listy wielokolumnowe (takie jak tablice sprintów). Kolejną funkcją, która może zostać dodana w przyszłości, jest komponent Dragon Drop React.
Obecnie Dragon Drop może być używany z Reactem, jak pokazano w poniższym demie, ale nie jest to idealne rozwiązanie, ponieważ zmiany DOM spowodowane zmianą kolejności listy nie są wychwytywane przez React, co może powodować nieoczekiwane zachowanie. Zachęcam każdego, kto znajdzie błędy w Dragon Drop, a nawet ma pomysły na funkcje, aby stworzyć problem na GitHub. Wszystkie opinie i wkład są mile widziane i bardzo mile widziane!