Gesaan dan skop
Ini adalah masalah interaksi kebolehcapaian dan Web Platform moden. Matlamatnya adalah menu, panel penapis atau permukaan bantuan yang membolehkan halaman kekal boleh digunakan sambil menyokong light-dismiss. HTML Popover API menggunakan popover, popovertarget dan top layer untuk menyediakan kitaran hayat paparan yang diuruskan oleh pelayar. Jangan memindahkan setiap tindanan ke API natif; kedudukan itu sendiri bukanlah latihan utama.
Perkara yang diuji oleh penemu duga
- Membezakan
popover="auto",popover="manual"dan semantik dialog modal. - Memastikan pencetus, permukaan dan tindakan tutup boleh difahami secara semantik.
- Mengendalikan Escape, klik luar, pelbagai permukaan, pemulangan fokus dan peristiwa kitaran hayat.
- Menjelaskan peningkatan progresif, sokongan pelayar dan sandaran (fallback) tanpa ralat.
Penjelasan untuk ditanya terlebih dahulu
Sahkan sama ada latar belakang kekal interaktif. Jika ia mesti disekat, gunakan <dialog> dengan showModal() dan bukannya popover. Jelaskan sama ada hanya satu permukaan boleh dibuka, sama ada beberapa permukaan manual boleh wujud bersama, sama ada pencetus bertindak sebagai togol, sama ada penghantaran borang yang berjaya menutupnya, dan julat pelayar minimum. Permukaan penapis biasanya bukan modal, tetapi pengguna papan kekunci masih memerlukan laluan fokus dan penutupan yang jelas.
Jawapan 30 saat
Mulakan dengan HTML semantik: letakkan popovertarget pada pencetus dan popover="auto" pada permukaan; gunakan manual hanya untuk orkestrasi penutupan tersuai. Pelayar membekalkan tingkah laku top-layer, Escape dan light-dismiss luar. Saya menambah kemasukan fokus, pemulangan fokus, teks status dan pengendalian kitaran hayat beforetoggle/toggle. Pelayar yang tidak disokong mengekalkan DOM dan nama yang sama dengan polyfill kecil dan bukannya pengendali klik global yang boleh menutup permukaan yang tidak berkaitan.
Penyelesaian langkah demi langkah
1. Pilih popover atau dialog modal
Popover sesuai untuk menu, penapis, bantuan tanpa sekatan dan tindakan sementara; halaman kekal bukan modal. <dialog> dengan showModal() sesuai untuk pengesahan, pembayaran atau amaran yang mesti dikendalikan terlebih dahulu kerana ia membekalkan semantik modal dan menyekat latar belakang. Kedua-duanya boleh menggunakan top layer, tetapi nama mudah diakses, strategi fokus dan sebab penutupannya berbeza; menggantikan dialog dengan atribut popover adalah tidak setara.
2. Wujudkan hubungan pencetus dan permukaan
Struktur semantik terkecil membolehkan pelayar mengekalkan hubungan sasaran:
<button type="button" popovertarget="filters" aria-controls="filters">
Filters
</button>
<div id="filters" popover="auto">
<form method="get">
<label>Status <select name="status"><option>All</option></select></label>
<button type="submit">Apply</button>
</form>
</div>popovertarget menjadikan butang sebagai pencetus deklaratif, dan pelayar mengurus hubungan semasa buka dan tutup. aria-controls boleh membantu teknologi bantuan memahami hubungan tersebut, tetapi ia tidak menggantikan nama yang boleh dilihat atau tingkah laku fokus yang betul. Komponen kompleks harus mengekalkan rujukan pencetus dalam skrip dan mengembalikan fokus kepadanya hanya jika ia masih wujud dan boleh difokuskan.
3. Fahami auto, manual dan light-dismiss
Popover auto menyokong light-dismiss yang diuruskan oleh pelayar: Escape atau klik luar boleh menutupnya, dan ia mengambil bahagian dalam rantaian penutupan automatik. Popover manual tidak ditutup oleh mekanisme tersebut; panggil showPopover(), hidePopover() atau togglePopover() secara eksplisit. Gunakannya apabila beberapa permukaan boleh wujud bersama atau kitaran hayat adalah tersuai. Jangan tambah penutupan klik peringkat dokumen di atas auto; permukaan bersarang dan klik pencetus boleh mengalami perebutan (race condition).
4. Kendalikan top layer, kedudukan dan latar belakang (backdrop)
Sebaik sahaja dibuka, popover memasuki top layer dan tidak lagi dikekang oleh konteks susunan overflow atau z-index milik leluhur biasa. Gunakan CSS Anchor Positioning atau susun atur biasa untuk penempatan, dengan sandaran statik apabila penempatan gagal. Popover bukan modal tidak sepatutnya menerima backdrop skrin penuh secara automatik; jika produk memerlukannya, semak semula sama ada keperluannya sebenarnya adalah tingkah laku dialog modal. Top layer mengubah susunan paparan tetapi tidak menyelesaikan isu viewport sempit, bekas tatal atau penempatan perlanggaran.
5. Tentukan fokus dan tingkah laku papan kekunci
Pindahkan fokus ke kawalan pertama yang boleh diambil tindakan, atau kekalkan tetapan lalai pelayar hanya selepas mengujinya. Pada Escape, kembalikan fokus kepada pencetus; jika pencetus telah dialih keluar, beralih kepada konteks kelihatan yang terdekat. Susunan tab harus merentasi permukaan secara semula jadi; jangan sembunyikan semua kawalan dengan tabindex="-1". Popover seperti menu memerlukan semantik kekunci anak panah dan pemilihan item menu, manakala borang penapis harus mengekalkan tingkah laku papan kekunci borang biasa.
6. Perhatikan kitaran hayat dan bukannya meneka keadaan global
Gunakan beforetoggle untuk mengesahkan peralihan, merekodkan sebab penutupan atau menyegerakkan keadaan aplikasi; gunakan toggle selepas keadaan benar-benar berubah untuk mengemas kini label dan fokus. Daftarkan pengendali bagi setiap elemen dan bersihkannya semasa pemusnahan komponen. Untuk permukaan auto yang saling eksklusif, bergantung pada tindanan penutupan pelayar dan bukannya mengekalkan ID terbuka global yang usang.
7. Selaraskan penghantaran borang dan keadaan aplikasi
Selepas penghantaran penapis berjaya, panggil hidePopover() secara eksplisit jika dikehendaki, tetapi jangan anggap penutupan sebagai bukti kejayaan. Pada permintaan yang gagal, pastikan permukaan terbuka dan kaitkan ralat dengan borang. Keadaan terbuka ialah keadaan UI sementara; nilai penapis ialah keadaan perniagaan. Pastikan ia berasingan, dan kira semula apabila terdapat perubahan navigasi atau sejarah dan bukannya menganggap :popover-open sebagai satu-satunya sumber kebenaran.
8. Gunakan peningkatan progresif dan uji interaksi
Kesan ciri API sebenar, seperti HTMLElement.prototype.showPopover. Gunakan tingkah laku natif apabila tersedia; jika tidak, kekalkan pencetus, kandungan dan nama mudah diakses yang sama dengan polyfill kecil untuk paparan, Escape, klik luar dan pemulangan fokus. Uji papan kekunci, sentuhan, zum, penatalan, permukaan bersarang, pencetus yang dialih keluar, borang yang gagal dan pengurangan pergerakan (reduced motion). Sahkan nama, keadaan dan ralat dengan pembaca skrin dan bukannya hanya memeriksa piksel sahaja.
Jawapan model
Saya akan mentakrifkan ini sebagai popover penapis bukan modal, bukan dialog. Butang menggunakan popovertarget dan panel menggunakan popover="auto"; pelayar menguruskan top layer, Escape dan light-dismiss luar, manakala skrip mengendalikan keadaan borang, pemulangan fokus dan peristiwa kitaran hayat. Semasa dibuka, fokus masuk ke kawalan pertama; semasa ditutup, ia kembali kepada pencetus. Penghantaran yang gagal memastikan permukaan kekal terbuka dan mendedahkan ralat; kejayaan boleh menutupnya. Gunakan manual hanya apabila beberapa permukaan tersuai mesti wujud bersama, dan jangan gandakan pengendalian klik dokumen untuk auto. Sediakan sandaran penempatan statik dan polyfill semantik apabila pengesanan ciri gagal. Uji laluan papan kekunci, sentuhan, tatal dan teknologi bantuan.
Kesilapan lazim
- Menggunakan popover untuk pengesahan yang mesti menyekat latar belakang, menyebabkan kehilangan semantik modal.
- Menambah penutupan klik dokumen pada
auto, yang boleh menutup permukaan bersarang atau kawalan hantar. - Menogol
displaytanpa mengekalkan hubungan pencetus, pemulangan fokus atau keadaan ralat. - Meniru dialog dengan backdrop skrin penuh sambil mengekalkan tingkah laku bukan modal.
- Menganggap top layer sebagai penempatan automatik dan mengabaikan penatalan, viewport sempit dan sandaran perlanggaran.
- Menutup borang yang gagal tanpa syarat sehingga pengguna tidak dapat melihat atau membetulkan ralat.
- Hanya menguji klik tetikus dan terlepas pandang tingkah laku Escape, Tab, sentuhan dan pembaca skrin.
Soalan susulan
Bilakah anda patut menggunakan <dialog> sebaliknya?
Gunakan <dialog> dengan showModal() apabila latar belakang mesti inert, pengguna mesti membuat keputusan terlebih dahulu, atau tingkah laku fokus modal diperlukan. Light-dismiss dan semantik bukan modal Popover tidak boleh menggantikan sekatan latar belakang dan tindakan batal/sahkan yang eksplisit.
Bagaimanakah anda menjadikan beberapa permukaan penapis saling eksklusif?
Utamakan auto untuk permukaan yang saling eksklusif supaya pelayar menguruskan rantaian penutupan. Jika beberapa permukaan manual boleh wujud bersama, kekalkan set tika yang eksplisit, tutup hanya tika yang disasarkan, dan simpan pencetus serta pemulangan fokus bagi setiap tika secara berasingan.
Bagaimanakah anda menyokong pelayar tanpa Popover API?
Kesan ciri API dan kekalkan DOM serta atribut semantik yang sama, dengan polyfill untuk paparan, tingkah laku tutup, Escape, klik luar dan pemulangan fokus. Jangan turunkan taraf kepada div berkedudukan mutlak tanpa nama dan tidak boleh diakses oleh papan kekunci; dokumentasikan matriks keserasian dan ujinya sebelum keluaran.
Bagaimanakah anda menguji sempadan light-dismiss?
Uji klik pada pencetus, di dalam permukaan, elemen adik-beradik luar, bekas tatal dan popover lain. Klik dalaman mesti kekal terbuka; klik luar hanya boleh menutup permukaan auto yang layak, dan klik pencetus berulang tidak boleh menghasilkan keadaan pendua. Tambahkan ujian Escape dan sentuhan.
Bolehkah animasi menjejaskan kebolehcapaian?
Gunakan prefers-reduced-motion untuk memendekkan atau mengalih keluar peralihan sambil memastikan fokus dan keadaan yang boleh dibaca kekal konsisten. Jangan sembunyikan kawalan yang boleh difokuskan dengan kelegapan (opacity) semata-mata; elakkan penghantaran pendua semasa penutupan dan dedahkan perubahan keadaan yang stabil kepada teknologi bantuan.
Bagaimana jika penempatan gagal?
Dengan kedudukan sauh (anchor positioning), sediakan sandaran aliran biasa atau selamat-viewport dan bertindak balas kepada perubahan saiz dan tatal. Kegagalan tidak boleh memotong kandungan atau menolaknya keluar dari skrin; borang teras kekal boleh digunakan tanpa peningkatan penempatan tersebut.