式 Web 設(shè)計課程實戰(zhàn):用 tabindex 精確控制多個元素的鍵盤焦點順序)
freeCodeCamp 響應(yīng)式 Web 設(shè)計課程實戰(zhàn)用 tabindex 精確控制多個元素的鍵盤焦點順序【免費下載鏈接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.項目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp在 freeCodeCamp 的課程體系中“應(yīng)用無障礙Applied Accessibility”是響應(yīng)式 Web 設(shè)計Responsive Web Design超區(qū)塊的收尾模塊而本模塊的最后一道挑戰(zhàn)正是講解tabindex的正整數(shù)值如何指定多個元素的鍵盤焦點Tab遍歷順序。讀完后你將掌握tabindex三種取值正數(shù)、0、負數(shù)各自對應(yīng)的焦點行為差異能按照“正數(shù)序列 → 默認元素 →tabindex0元素”的規(guī)則手工排布頁面的 Tab 導航流并完整復現(xiàn)課程練習在一個名言頁面上讓搜索框和提交按鈕成為鍵盤用戶最先接觸到的兩個控件同時理解為什么正數(shù)tabindex在無障礙實踐中需要謹慎使用。挑戰(zhàn)在課程體系中的位置該挑戰(zhàn)文件位于 applied-accessibility 模塊模塊標題為 “Use tabindex to Specify the Order of Keyboard Focus for Several Elements”使用 tabindex 指定多個元素的鍵盤焦點順序challengeType為 0屬于 HTML 交互式挑戰(zhàn)。從 模塊結(jié)構(gòu)文件 可以確認它是applied-accessibility區(qū)塊 22 道挑戰(zhàn)中的最后一道其前一道挑戰(zhàn) Use tabindex to Add Keyboard Focus to an Element 剛剛講完了tabindex0與負值的基礎(chǔ)用法。整個區(qū)塊又隸屬于 responsive-web-design 超區(qū)塊結(jié)構(gòu) 的一部分幫助類別標注為 HTML-CSS。tabindex 的三種取值先看全景再聚焦正數(shù)要理解本挑戰(zhàn)需要先把tabindex的完整語義放在一起看這部分承接前一道挑戰(zhàn)的內(nèi)容取值行為正整數(shù)1、2、…元素進入自定義 Tab 序列按數(shù)值升序優(yōu)先于默認焦點流0元素可被鍵盤聚焦按 HTML 源碼位置參與默認焦點流負數(shù)通常為 -1元素可以被程序化聚焦但不能通過鍵盤 Tab 到達默認情況下鏈接、表單控件等天然可聚焦元素會按照它們在 HTML 源碼中出現(xiàn)的順序獲得焦點。給div、span、p這類非表單元素加上tabindex0可以使其按源碼位置加入默認焦點流而負值典型為 -1一般用于彈窗等需要由腳本調(diào)用focus()的場景。本挑戰(zhàn)聚焦的就是正整數(shù)這一支當tabindex的值設(shè)置為 1 或更大的正數(shù)時它指定了元素的精確 Tab 順序。正數(shù) tabindex 的焦點順序規(guī)則核心行為可以歸納為一條遍歷規(guī)則值為tabindex1的元素最先獲得鍵盤焦點之后依次循環(huán)經(jīng)過tabindex2、tabindex3等按數(shù)值升序排列的元素遍歷完所有正數(shù)序列后才輪到默認可聚焦元素以及tabindex0的元素這部分恢復按 HTML 源碼順序遍歷。課程給出的最簡示例是div tabindex1I get keyboard focus, and I get it first!/divdiv tabindex2I get keyboard focus, and I get it second!/div按規(guī)則第一個div先于第二個div獲得焦點即使它們在源碼中的位置被其他元素分隔也不影響這個順序。需要特別注意的是這種設(shè)定方式會覆蓋默認的焦點順序默認順序以 HTML 源碼為準。如果鍵盤用戶預期從頁面頂部自然開始導航卻被直接“拽”到頁面中部的某個控件體驗會相當混亂。因此課程原文的結(jié)論是這種技巧在某些場景下確有必要但從無障礙角度講應(yīng)用之前務(wù)必謹慎。實戰(zhàn)練習讓搜索框成為 Tab 流的前兩項挑戰(zhàn)設(shè)定了一個具體場景Camper Cat 在他的 “Inspirational Quotes”勵志名言頁面上有一個搜索框他計劃用 CSS 把它定位到頁面右上角。由于視覺上它被移到了頁首他希望搜索輸入框和提交按鈕成為 Tab 順序中的前兩項——這正是正數(shù)tabindex的典型適用場景視覺位置與源碼位置解耦后用焦點順序把兩者重新對齊。具體要求給search輸入框添加tabindex1給submit輸入框添加tabindex2。初始代碼seed中form部分留了兩個空行待填寫body div tabindex1 classoverlay/div header h1Even Deeper Thoughts with Master Camper Cat/h1 nav ul lia hrefHome/a/li lia hrefBlog/a/li lia hrefTraining/a/li /ul /nav /header form label forsearchSearch:/label input typesearch namesearch idsearch input typesubmit namesubmit valueSubmit idsubmit /form h2Inspirational Quotes/h2 blockquote pldquo;Theres no Theory of Evolution, just a list of creatures Ive allowed to live.rdquo;br - Chuck Norris/p /blockquote blockquote pldquo;Wise men say forgiveness is divine, but never pay full price for late pizza.rdquo;br - TMNT/p /blockquote footercopy; 2018 Camper Cat/footer /body style body { height: 100%; margin: 0 !important; padding: 8px; } .overlay { margin: -8px; position: absolute; width: 100%; height: 100%; } /style標準解法solutions只在兩個input上各加一個屬性其余保持不動form label forsearchSearch:/label input tabindex1 typesearch namesearch idsearch input tabindex2 typesubmit namesubmit valueSubmit idsubmit /formoverlay 元素的作用課程說明中還有一個容易忽略的細節(jié)某些瀏覽器在用戶點擊頁面上某個元素后可能會把焦點起點放到 Tab 順序的中間位置。為了保證鍵盤用戶總能從 Tab 順序的起點開始頁面里額外添加了一個元素來承擔這個職責——也就是 seed 開頭那個div tabindex1 classoverlay/div。從源碼結(jié)構(gòu)看它以絕對定位鋪滿整個視口position: absolute; width: 100%; height: 100%配合負margin抵消 body 內(nèi)邊距并且自身也持有tabindex1且位于所有其他正數(shù)焦點元素之前。這樣無論上一次點擊把焦點帶到哪里下一次 Tab 都能回到序列頭部保證“先搜索框、后提交按鈕”的練習結(jié)果穩(wěn)定可復現(xiàn)。自動化校驗hints 斷言如何驗證你的修改該挑戰(zhàn)附帶了四條自動化斷言它們也是理解驗收標準最直觀的方式// 1. search 輸入框必須存在 tabindex 屬性 assert.isNotNull(document.querySelector(#search)?.getAttribute(tabindex)); // 2. submit 輸入框必須存在 tabindex 屬性 assert.isNotNull(document.querySelector(#submit)?.getAttribute(tabindex)); // 3. search 的 tabindex 值必須為字符串 1 assert.equal(document.querySelector(#search)?.getAttribute(tabindex), 1); // 4. submit 的 tabindex 值必須為字符串 2 assert.equal(document.querySelector(#submit)?.getAttribute(tabindex), 2);注意后兩條斷言比較的是字符串1和2——HTML 屬性取回的值始終是字符串這提醒我們tabindex在 DOM 層面的存儲形態(tài)與在行為層面的整數(shù)值解析是兩回事。在 freeCodeCamp 的前端中這類 HTML 挑戰(zhàn)由 Challenges 模板 在瀏覽器內(nèi)渲染并執(zhí)行上述斷言完成自動判分。小結(jié)正數(shù) tabindex 的適用邊界把本挑戰(zhàn)與前一道tabindex0的挑戰(zhàn)對照可以形成一條清晰的決策線元素需要按源碼順序獲得鍵盤焦點 → 用tabindex0適用于非表單元素如前一個挑戰(zhàn)中讓p聚焦并觸發(fā):focus樣式的場景需要讓元素脫離源碼位置、搶占焦點序列的前端典型如被 CSS 重排到視覺頁首的控件→ 用tabindex1、2等正整數(shù)并接受它會覆蓋默認焦點順序的代價只需要腳本聚焦如彈窗→ 用負值-1不進入鍵盤 Tab 流。課程給出的告誡值得原樣保留正數(shù)tabindex會重寫用戶預期的導航起點可能造成困惑因此在無障礙層面應(yīng)當謹慎使用。這也是該挑戰(zhàn)放在整個無障礙模塊最后一道的用意——先教會你“能做”同時明確要求你“知道何時不該做”?!久赓M下載鏈接】freeCodeCampfreeCodeCamp.orgs open-source codebase and curriculum. Learn math, programming, and computer science for free.項目地址: https://gitcode.com/GitHub_Trending/fr/freeCodeCamp創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考