Masalah dan Kes Penggunaan
Navigasi dokumen penuh menggantikan dokumen dan tajuknya. Navigasi SPA lembut (soft navigation) mengekalkan dokumen yang sama, jadi fokus boleh kekal pada pautan yang kandungan sekelilingnya telah hilang. Pengguna pembaca skrin mungkin tidak mendengar sebarang petunjuk berguna bahawa produk baharu, langkah pembayaran atau halaman ralat telah sedia.
Dasar ini mesti merangkumi lima peralihan yang berbeza: pemuatan awal, perubahan laluan yang dimulakan pengguna, penapis atau pengisihan di tempat yang sama (in-place), navigasi yang diganti atau dibatalkan, dan Back/Forward penyemak imbas. Ia juga mesti wujud bersama dengan tingkah laku milik komponen seperti dialog. Matlamatnya adalah konteks yang boleh diramal, bukannya mengalihkan fokus selepas setiap mutasi URL.
Perkara yang Dinilai oleh Penemu Duga
Penemu duga sedang mencari model keputusan semantik. "Fokuskan tajuk pada setiap perubahan laluan" kedengaran mudah diakses tetapi merosakkan penapis, perubahan hash, penghidratan awal dan pemulihan sejarah. Jawapan yang kukuh terlebih dahulu memutuskan sama ada tugasan pengguna telah berubah.
Mereka juga menjangkakan pengetahuan tentang penyemak imbas: tajuk boleh menerima fokus secara programatik dengan tabIndex={-1} tanpa menyertai susunan Tab berurutan; focus() biasanya menatal elemen tersebut; preventScroll memisahkan pemulihan fokus daripada pemulihan tatalan; dan nilai positif tabindex mencipta susunan fokus yang rapuh.
Akhir sekali, jawapan mesti mengendalikan konkurensi. Jika laluan B selesai selepas laluan C, B tidak boleh mengemas kini tajuk atau mencuri fokus. Pemeriksaan automatik boleh membuktikan elemen aktif, tajuk dan susunan, tetapi tidak dapat membuktikan perkara yang diumumkan oleh setiap pasangan penyemak imbas dan teknologi bantuan.
Soalan Penjelasan Sebelum Menjawab
- Peralihan manakah yang memulakan tugasan baharu? Produk-ke-pembayaran memulakannya; menukar susunan pengisihan biasanya tidak. Ini menentukan sama ada fokus dialihkan atau kekal pada kawalan pemula.
- Bilakah laluan dikomit? Fokus harus dijalankan hanya apabila laluan yang menang telah merender tajuk utama akhirnya, bukan pada klik, mutasi URL atau paparan rangka (skeleton).
- Apakah yang mengawal tindanan (overlays)? Dialog mengekalkan fokus awal, perangkap (trap) dan kontrak kembalikan fokusnya sendiri. Dasar laluan tidak boleh bersaing dengannya.
- Apakah yang dipulihkan oleh sejarah? Tentukan sama ada produk memerlukan fokus, tatalan atau kedua-duanya bagi setiap entri sejarah. Kedua-duanya memerlukan penyelarasan untuk mengelakkan lompatan berganda.
- Penyemak imbas dan teknologi bantuan manakah yang disokong? Tingkah laku pengumuman berbeza-beza, jadi matriks keluaran mestilah eksplisit.
- Bolehkah setiap laluan menyediakan tajuk deskriptif dan satu tajuk utama (heading)? Jadikan ini sebahagian daripada kontrak laluan; gunakan tanda tempat (landmark) main hanya sebagai sandaran terkawal.
Rangka Kerja Jawapan 30 Saat
"Saya mengklasifikasikan navigasi sebelum mengalihkan fokus. Pemuatan awal tidak melakukan apa-apa. Perubahan tugasan yang dimulakan pengguna yang telah dikomit mengemas kini tajuk dokumen dan memfokuskan H1 deskriptif baharu, yang dijadikan boleh difokuskan secara programatik dengan tabIndex=-1. Penapis tugasan yang sama mengekalkan kawalan dan melaporkan hasil yang lengkap melalui kawasan status sopan (polite status region) yang berterusan. Setiap navigasi mempunyai token, jadi hanya laluan dikomit terkini boleh menggunakan tajuk dan fokus. Pada Back/Forward saya memulihkan sasaran semantik sah yang disimpan untuk entri sejarah tersebut, jika tidak saya menggunakan H1, menyelaraskan fokus dengan pemulihan tatalan. Saya menguji pemuatan awal, navigasi pantas, ralat, penapis, sejarah, susunan papan kekunci, fokus kelihatan dan pembaca skrin sebenar."
Penyelaman Mendalam Langkah demi Langkah
Mulakan dengan jadual peralihan:
| Peralihan | Tindakan fokus | Pengumuman |
|---|---|---|
| Pemuatan awal atau penghidratan | Jangan paksa fokus | Tingkah laku dokumen/tajuk asli |
| PUSH ke tugasan baharu | Fokuskan H1 laluan yang dikomit | Tajuk dikemas kini ditambah tajuk utama difokuskan |
| Penapis, pengisihan atau penomboran halaman dalam tugasan yang sama | Kekalkan kawalan pemula | Kemas kini hasil/status sopan jika berguna |
| POP daripada Back/Forward | Pulihkan sasaran sah yang disimpan; jika tidak H1 | Konteks dipulihkan atau tajuk utama difokuskan |
| Laluan lencongan atau ralat | Fokuskan H1 laluan tersebut yang telah dikomit | Tajuk dan tajuk utama akhirnya |
| Dialog buka/tutup | Patuhi kontrak dialog | Label dialog dan sasaran kembali |
Kontrak laluan membekalkan tajuk akhir, rujukan (ref) H1 deskriptif dan kunci laluan semantik. Berikan H1 tabIndex={-1}. Ia kekal di luar jujukan Tab biasa, tetapi kod boleh memfokuskannya. Kekalkan penunjuk fokus yang kelihatan. Pautan langkau kekal sebagai kawalan boleh fokus papan kekunci yang pertama dan menyasarkan main; ia menyelesaikan pintasan navigasi berulang dan masih bernilai apabila fokus laluan diuruskan.
Fokus adalah milik sempadan komit. Berikan setiap navigasi yang dicuba token yang meningkat secara monotonik. Apabila data dan UI untuk laluan selesai, gunakan kesan hanya jika tokennya masih terkini dan H1 telah dimuatkan. Jangan gunakan tamat masa tetap: kelajuan rangkaian dan kerja rendering menjadikannya tidak boleh dipercayai.
beginNavigation(kind):
token = nextToken()
rememberCurrentFocus(historyEntryKey)
commitRoute(token, kind, title, heading):
if token != currentToken or heading is not connected:
return
document.title = title
if kind is PUSH or semantic-task REPLACE:
heading.focus()
else if kind is POP:
focus(validSavedTarget(historyEntryKey) or heading)Simpan ID fokus tempatan laluan yang stabil dan bukannya laluan CSS yang dijana. Pada POP, pulihkannya hanya jika elemen masih wujud, kelihatan, didayakan dan bermakna dalam keadaan yang dipulihkan. Jika tidak, gunakan H1. Jika penghala memulihkan tatalan secara berasingan, gunakan focus({ preventScroll: true }) dan kemudian pulihkan tatalan sekali; untuk PUSH biasa, membenarkan fokus mendedahkan H1 biasanya lebih jelas.
Elakkan pertuturan pendua. Memfokuskan H1 baharu selepas mengemas kini tajuk selalunya membekalkan konteks yang mencukupi, walaupun pertuturan sebenar berbeza mengikut teknologi bantuan. Jangan umumkan tajuk yang sama dalam kawasan langsung secara lalai. Bagi penapis yang mengekalkan fokus, kawasan role="status" atau aria-live="polite" yang berterusan boleh mengumumkan kiraan hasil yang telah selesai. Simpan pengumuman tegas (assertive) untuk maklumat yang benar-benar mendesak kerana ia boleh mengganggu pertuturan semasa.
Orakel ujian mengikut dasar. Pada penghidratan awal, aplikasi tidak boleh mencuri fokus. Pada PUSH, selepas komit akhir, document.activeElement ialah H1 baharu, tajuk adalah muktamad, dan Tab seterusnya mencapai elemen interaktif logik yang pertama. Pada perubahan penapis, pencetus mengekalkan fokus dan teks status dikemas kini sekali. Dalam perlumbaan A→B→C di mana B selesai paling akhir, C mengekalkan tajuk dan fokus. Laluan ralat dan lencongan memfokuskan tajuk utama mereka sendiri. POP memulihkan sasaran sah yang disimpan atau kembali kepada sandaran secara deterministik.
Jalankan pemeriksaan DOM automatik untuk semua kes tersebut, termasuk penanggalan sasaran dan reka letak pergerakan berkurang/zum. Kemudian lakukan penelusuran secara manual dengan papan kekunci dan gabungan yang disokong seperti VoiceOver/Safari dan NVDA atau JAWS dengan penyemak imbas yang disokong. Sahkan fokus kelihatan, susunan logik, tiada tatalan yang tidak dijangka dan pengumuman yang boleh difahami. Rekod versi penyemak imbas dan teknologi bantuan kerana output pertuturan adalah hasil integrasi, bukan jaminan DOM.
Contoh Jawapan Berkualiti Tinggi
"Saya akan menjadikan tingkah laku fokus sebagai sebahagian daripada kontrak semantik penghala. Setiap laluan mendedahkan tajuk dokumen akhir dan rujukan H1 deskriptif. Saya mengklasifikasikan peralihan: penghidratan awal tidak mengalihkan fokus; PUSH yang dimulakan pengguna yang mengubah tugasan memfokuskan H1 akhir selepas komit; penapis atau pengisihan mengekalkan kawalan pemula; dan POP cuba memulihkan sasaran stabil yang disimpan sebelum beralih kepada H1 sebagai sandaran.
H1 mempunyai tabIndex=-1, jadi ia boleh difokuskan secara programatik tanpa menambah hentian Tab tambahan. Saya mengekalkan gaya fokus yang kelihatan dan mengekalkan pautan langkau yang menyasarkan main. Tajuk dan fokus berubah bersama-sama hanya selepas laluan yang menang dikomit. Setiap navigasi menerima token, dan penyelesaian tak segerak yang lebih lama diabaikan, yang menghalang laluan yang dibatalkan daripada mencuri fokus.
Untuk sejarah, saya menyimpan ID fokus tempatan laluan semantik bagi setiap entri sejarah. Saya memulihkan hanya sasaran yang disambungkan, kelihatan dan didayakan. Jika pemulihan tatalan adalah berasingan, saya memfokuskan dengan preventScroll dan memulihkan tatalan sekali. Kemas kini tak segerak dalam tugasan yang sama menggunakan kawasan status sopan yang berterusan; saya mengelak daripada mengulang tajuk laluan dalam kedua-dua tajuk utama dan kawasan langsung.
Saya akan mengautomasikan penegasan untuk elemen aktif, tajuk, susunan Tab, pengekalan penapis, navigasi pantas A→B→C, lencongan, ralat dan sandaran POP. Saya kemudiannya akan menguji pertuturan sebenar, fokus kelihatan dan penatalan dengan matriks papan kekunci dan pembaca skrin yang disokong. Itu memisahkan tingkah laku DOM deterministik daripada tingkah laku teknologi bantuan yang mesti kita perhatikan."
Kesilapan Biasa
- Fokus pada setiap perubahan URL → penapis dan perubahan hash mengganggu tugasan → klasifikasikan peralihan semantik terlebih dahulu.
- Fokus apabila pautan diklik → destinasi mungkin tidak wujud atau mungkin dibatalkan → fokus hanya pada laluan dikomit yang menang.
- Gunakan tamat masa (timeout) → render perlahan dan pantas berlumba secara berbeza → gunakan kitaran hayat laluan dan token navigasi.
- Fokus
bodyatau tambahtabindexpositif → konteks dan susunan menjadi tidak jelas → gunakan H1 deskriptif dengantabIndex=-1. - Sentiasa lompat ke H1 pada POP → Back menghilangkan kedudukan pengguna → pulihkan sasaran sejarah yang sah dengan sandaran deterministik.
- Umumkan tajuk dua kali → pengguna mendengar pertuturan berlebihan → pilih konteks tajuk utama yang difokuskan dahulu dan gunakan status langsung untuk kemas kini di tempat yang sama.
- Anggap imbasan kebolehcapaian automatik sebagai bukti → ia tidak dapat mengesahkan output pertuturan sebenar → tambah ujian papan kekunci dan teknologi bantuan manual.
Soalan Susulan dan Maklum Balas
Susulan 1: Mengapa tidak sentiasa memfokuskan tanda tempat main?
H1 biasanya memberikan nama yang lebih khusus untuk tugasan baharu. main ialah sandaran yang munasabah apabila kontrak laluan tidak dapat membekalkan tajuk utama, tetapi memastikan setiap laluan menyediakannya menambah baik struktur kelihatan, garis bentuk dokumen dan kebolehujian.
Susulan 2: Patutkah navigasi tetikus juga mengalihkan fokus?
Jika tindakan yang dimulakan pengguna menggantikan tugasan utama, konteks yang konsisten adalah berguna tanpa mengira peranti input, termasuk untuk pengguna pembaca skrin yang mengklik. Dasarkan keputusan pada navigasi semantik, bukan tekaan tentang penggunaan papan kekunci. Elakkan mengalihkan fokus untuk muat semula latar belakang.
Susulan 3: Bagaimana jika B selesai selepas C dalam navigasi pantas?
Token B tidak lagi sepadan dengan navigasi semasa, jadi kesan komitnya kembali tanpa mengubah tajuk, fokus atau status. Menggugurkan permintaan B menjimatkan kerja, tetapi pemeriksaan token masih diperlukan kerana pembatalan mungkin lewat atau tidak disokong.
Susulan 4: Bagaimanakah fokus dan pemulihan tatalan berinteraksi?
focus() biasa boleh menatal sasaran ke dalam paparan. Pada POP, jika penghala memulihkan kedudukan tatalan yang disimpan secara berasingan, gunakan preventScroll, sahkan dan fokuskan elemen yang disimpan, kemudian lakukan satu pemulihan tatalan. Tentukan satu pemilik supaya fokus dan kod penghala tidak bertembung.
Susulan 5: Bilakah kawasan langsung harus bersifat tegas (assertive)?
Hanya apabila pendengaran yang tertangguh menimbulkan masalah serius, seperti mesej sesi atau keselamatan yang mendesak. Kiraan hasil biasa dan kemas kini penyiapan hendaklah bersifat sopan (polite). Konteks laluan biasanya datang daripada tajuk akhir dan tajuk utama yang difokuskan, mengelakkan pengumuman kedua.
Susulan 6: Adakah ini pematuhan WCAG dengan sendirinya?
Tidak. Ia menyokong susunan fokus dan konteks yang boleh difahami dalam aplikasi dinamik, tetapi pematuhan juga bergantung pada semantik, nama, operasi papan kekunci, kontras, pengendalian ralat dan kriteria lain. Uji keseluruhan perjalanan pengguna terhadap sasaran pematuhan produk.