Saat mengembangkan aplikasi, vendor front-end jarang memperhatikan bagaimana pengguna akan menggunakan fungsi keyboard yang disediakan oleh browser. Saya bukan pengecualian, tetapi suatu hari saya diberi tugas tentang UX dan transisi dengan menekan "Tab" dan "Shift + Tab".
Inti dari tugas ini transparan dan bersih: ada antarmuka, tata letak yang ditampilkan di bawah ini. Secara konseptual, 1 halaman dapat berisi 2 formulir yang berbeda dan persyaratannya adalah "berjalan dengan Tab tidak berpindah dari satu formulir ke formulir lain".

Semuanya akan baik-baik saja jika browser tahu bagaimana "secara asli" memblokir fokus dalam bentuk. Contoh disajikan pada gambar di bawah ini, di mana "border`om oranye menandai elemen saat ini, dan abu-abu - yang sebelumnya.
οΏΌ

Seperti yang Anda lihat, perilaku "pribumi" tidak memenuhi persyaratan. Jadi, mari kita selesaikan masalah ini. Solusinya tidak rumit, jadi pertimbangkanlah.
Akan ideal jika ada beberapa "gerbang" yang akan mencegah "melompat" fokus dari yang terakhir (dengan "Tab") atau elemen pertama (dengan "Shift + Tab") dengan
"tabindex" atau mendukung fokus secara default. Jadi, intinya sederhana: "gerbang" kita adalah "elemen masukan" tersembunyi, yang menerima acara "peristiwa" sebagai argumen selama acara "onFocus" dan mengembalikan fokus ke elemen dari mana asalnya. Ilustrasi di bawah.

Mendapatkan elemen sebelumnya layak menggunakan properti "relatedTarget" dari objek "event". Visualisasi solusi di bawah ini.
οΏΌ

Dan ini kodenya sendiri. Perlu dicatat bahwa tidak ada sintaks "ES6 +", karena gagasan mendukung kode dengan browser yang berbeda tanpa menghubungkan berbagai "transpiler" seperti Babel pada intinya.
function getGateInput(handleTabOut) { var input = document.createElement("input");
Tidak ada yang rumit: "input" dibuat, gaya diatur yang "menyembunyikan" gerbang kami. Di sini, "display: none" tidak digunakan, karena browser tidak memfokuskan "Tabs" pada elemen-elemen tersebut. Karena perilaku ini, diperlukan untuk membuat elemen transparan dan memindahkannya dari jendela browser.
function getTabOutHandler(element, GATES) { return function(event) { var relatedTarget = event.relatedTarget || event.fromElement; var target = event.target; var gatesTrapped = target === GATES[0] || target === GATES[1]; if (gatesTrapped && isChild(relatedTarget, element)) { event.preventDefault(); relatedTarget.focus(); } }; }
Untuk mengembalikan fokus ke item sebelumnya, gunakan getTabOutHandler. Ini adalah
HOC . Argumen pertama adalah wadah kami (yang ada di sekitar tempat kami mengatur "gerbang"), dan yang kedua mengharapkan array "gerbang" yang kami buat menggunakan getGateInput. Fungsi ini mengembalikan event handler yang bekerja sesuai dengan prinsip yang dijelaskan di atas.
Agar fokus bisa masuk ke dalam wadah, kita perlu membuka dan menutup "gerbang". Kami akan melakukan ini dengan mengatur atribut
"tabindex" . (-1 - jangan fokus dengan Tab, 0 - fokus sesuai aliran)
function moveGates(open, GATES) { GATES[0].setAttribute("tabindex", open ? -1 : 0); GATES[1].setAttribute("tabindex", open ? -1 : 0); }
Untuk mengontrol gerbang, kita akan mengatur pawang yang akan "mendengarkan" untuk menekan Tab (kode 9) dan jika elemen fokus (activeElement) ada di dalam wadah, tutup "gerbang", jika tidak buka.
window.addEventListener("keydown", function(event) { if (event.keyCode === 9) { if (isChild(document.activeElement, element)) { moveGates(false, GATES); } else { moveGates(true, GATES); } } });
Total
Metode untuk mengunci fokus dalam formulir dipertimbangkan, yang terdiri dari mengembalikan fokus ke elemen fokus sebelumnya. Untuk "menangkap" fokus, kami menggunakan "elemen input" tersembunyi, yang fokusnya dikontrol menggunakan
"tabindex" . Kode di atas adalah bagian dari perpustakaan
tab-out-catcher yang saya tulis untuk menyelesaikan masalah saya. Contoh penggunaan dapat ditemukan di
sini . Ada juga
solusi untuk Bereaksi aplikasi.