摘要:鍵盤訪問的升級提供快捷方式不過,在訪問網(wǎng)格時,通過鍵盤進行兩個方向的移動會不會更好呢使用一點做漸進增強,我們做到了,可以使用鼠標或方向鍵訪問網(wǎng)格。在本例總共,查找表名字是。
厚著臉做推廣,個人網(wǎng)站 http://www.wemlion.com/。
本文轉載自:眾成翻譯
譯者:文藺
鏈接:http://www.zcfy.cc/article/1179
原文:https://www.christianheilmann.com/2016/08/15/better-keyboard-navigation-with-progressive-enhancement/
創(chuàng)建界面時很重要的一點是,要考慮到那些只依賴鍵盤來使用產品的用戶。這對可訪問性來說是基本要求,在多數(shù)情況下,通過鍵盤操作訪問也并非難事。這意味著首先,也是最重要的,是使用鍵盤可訪問元素進行交互。
如果希望用戶跳轉到其他地方,使用帶有有效的 href 屬性的錨點連接
如果希望用戶執(zhí)行你自己的代碼,并在當前文檔中停留,使用按鈕
通過流動 tabIndex 技術幾乎可以使所有內容都能通過鍵盤訪問,不過,既然已經(jīng)有 HTML 元素可以做同樣的事情,又何必再麻煩呢。
效果可視化不過,使用恰當?shù)脑夭⒉荒敲春唵危挥脩翩I盤在元素集合中所處的位置,也要顯眼一些。給激活的元素加上輪廓(outline),瀏覽器解決了這個問題。這雖然超有用,但卻是一些人的眼中釘,他們希望由自己控制所有交互的視覺展現(xiàn)。在 CSS 中將 outline 屬性設置為 none,就能移除這個視覺輔助功能;不過這會帶來不小的可訪問性問題,除非你提供一個別的替代。
使用最顯眼的 HTML 元素;加上一些 CSS,確保除 hover 之外 focus 狀態(tài)同樣也被定義。這樣就可以使用戶在列表中的一個個項目間,輕松地通過 tab 來切換了。Shift + Tab 允許回退。可以看下 demo,HTML 挺簡單粗暴的。
使用列表,為我們的元素賦予了層次結構,以及普通瀏覽器所沒有的可訪問性技術的導航方式。它還帶來很多 HTML 元素,我們可以自己添加樣式。通過一點樣式,我們可以將其轉換為網(wǎng)格,占用更少的垂直空間,容納更多內容。
ul, li { margin: 0; padding: 0; list-style: none; } button { border: none; display: block; background: goldenrod; color: white; width: 90%; height: 30px; margin: 5%; transform: scale(0.8); transition: 300ms; } button:hover, button:focus { transform: scale(1); outline: none; background: powderblue; color: #333; } li { float: left; } /* grid magic by @heydonworks https://codepen.io/heydon/pen/bcdrl */ li { width: calc(100% / 4); } li:nth-child(4n+1):nth-last-child(1) { width: 100%; } li:nth-child(4n+1):nth-last-child(1) ~ li { width: 100%; } li:nth-child(4n+1):nth-last-child(2) { width: 50%; } li:nth-child(4n+1):nth-last-child(2) ~ li { width: 50%; } li:nth-child(4n+1):nth-last-child(3) { width: calc(100% / 4); } li:nth-child(4n+1):nth-last-child(3) ~ li { width: calc(100% / 4); }
結果看起來非常棒,在查看列表的過程中,我們能清楚地看到自己所處的位置。
鍵盤訪問的升級 —— 提供快捷方式不過,在訪問網(wǎng)格時,通過鍵盤進行兩個方向的移動會不會更好呢?
使用一點 JavaScript 做漸進增強,我們做到了,可以使用鼠標或方向鍵訪問網(wǎng)格。
不過記著,這僅僅只是一個增強。假設 JavaScript 因為各種可能的原因執(zhí)行失敗,依然可以通過 tab 來訪問列表,我們失去的只是便利,但至少還有可用的界面。
我將這個打包成了一個小巧、無依賴的開源 JavaScript 項目 gridnav,可以在 GitHub 上獲取代碼。你要做的就是調用腳本,傳給它一個選擇器以獲取元素列表。
通過列表元素的 data- 屬性,可以自己定義每行元素的數(shù)量以及鍵盤可訪問的元素。這些是可選的,但設置之后會讓代碼更快,出錯可能性更小。README 文件更詳細地解釋了如何使用。
工作原理開始考慮如何做的時候,像任何開發(fā)者一樣,抓到了最復雜的方式。我以為,需要對父節(jié)點、兄弟節(jié)點的大量定位比較,使用上 getBoundingClientRect,進行大量的 DOM 訪問。
之后我往回走了一步,意識到如何展示列表并不重要。最終不過是一個列表,我們要訪問它而已。甚至不需要訪問 DOM,因為我們所做的不過是從一堆按鈕或錨點連接中的一個切換到另一個。我們要做的就是:
找到當前所在元素(event.target)。
獲取按下的鍵。
根據(jù)鍵向前向后移動,或跳過一些元素到下一行。
就像這樣(點擊這里試試看):
我們需要跳過的元素數(shù)量是由每行的元素數(shù)量決定的。向上等同于向前 n 個元素,向下相當于向后 n 個元素。
使用一些小技巧,完整代碼非常簡短:
(function(){ var list = document.querySelector("ul"); var items = list.querySelectorAll("button"); var amount = Math.floor( list.offsetWidth / list.firstElementChild.offsetWidth ); var codes = { 38: -amount, 40: amount, 39: 1, 37: -1 }; for (var i = 0; i < items.length; i++) { items[i].index = i; } function handlekeys(ev) { var keycode = ev.keyCode; if (codes[keycode]) { var t = ev.target; if (t.index !== undefined) { if (items[t.index + codes[keycode]]) { items[t.index + codes[keycode]].focus(); } } } } list.addEventListener("keyup", handlekeys); })();
這里發(fā)生了什么?
首先我們獲取到了列表元素,并緩存所有可通過鍵盤訪問的元素:
var list = document.querySelector("ul"); var items = list.querySelectorAll("button");
計算每次上下移動需要跳過的元素數(shù)量,將列表的寬度除以列表第一個子元素(本例中是 LI)的寬度即可:
var amount = Math.floor( list.offsetWidth / list.firstElementChild.offsetWidth );
相較于 switch 語句或者大量的 if 判斷,我更樂意使用查找表。在本例總共,查找表名字是 codes。向上鍵值為 38,向下 40,向左 37,向右 39。假如我們拿到了 codes[37],值為 -1,也就是我們要在列表中移動的數(shù)量:
var codes = { 38: -amount, 40: amount, 39: 1, 37: -1 };
可以使用 event.target 獲取按下鍵盤時列表中的選中元素,但我們不知道它在列表中的位置。為避免重復遍歷列表,一次性遍歷所有按鈕,將它們在列表中的索引存儲在按鈕自身的 index 屬性中。
for (var i = 0; i < items.length; i++) { items[i].index = i; }
handlekeys() 完成剩余工作。讀取所按按鍵的鍵值,然后到 codes 中查找。所以,我們只針對方向鍵做出響應。接著獲取當前的元素,檢查其是否有 index 屬性。如果有,則檢查我們將要移到的位置是否有元素存在。如果元素存在,則獲得焦點。
function handlekeys(ev) { var keycode = ev.keyCode; if (codes[keycode]) { var t = ev.target; if (t.index !== undefined) { if (items[t.index + codes[keycode]]) { items[t.index + codes[keycode]].focus(); } } } }
給列表綁定一個 keyup 事件監(jiān)聽器,搞定 :)
list.addEventListener("keyup", handlekeys);
如果你想看真實效果,這有一個講述各個細節(jié)的快速視頻教程。
視頻在最后的代碼部分有點 bug,因為我沒將 count 屬性和 undefined 對比,所以在第一個元素上,鍵盤功能沒法正常工作(0 是 falsy)。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/111492.html
摘要:這里使用到的最多的中的屬性,即媒體查詢響應式設計實踐原則漸進增強漸進增強英語是網(wǎng)頁設計的一種策略,強調可訪問性,語義標記,外部樣式表和腳本技術。 1、響應式設計關鍵點在于: 媒體查詢、流動網(wǎng)格、彈性圖片,而不是flex布局或者是自適應布局 響應式和自適應的最直觀的區(qū)別是:自適應是為了解決如何才能在不同大小的設備上呈現(xiàn)同樣的網(wǎng)頁,直觀地來看就是盒子會根據(jù)屏幕分辨率的大小進行伸縮變換。所以...
摘要:前言本篇文章是基礎知識的篇,如果前面的基礎知識入門篇看完了,現(xiàn)在就可以學習了。基本概念分為三個部分。在這個基礎上使用一些新特性,高級瀏覽器支持,低級瀏覽器不支持。在對象中的屬性是一個布爾值,只有和。 showImg(https://segmentfault.com/img/remote/1460000012581493?w=1920&h=1080); DOM 前言 本篇文章是JavaS...
摘要:最后,我們必須調用函數(shù)來檢查所有的漸進式圖片容器在首次運行時是否在頁面上可見。我們還必須在滾動頁面或調整瀏覽器大小時調用函數(shù),在一些舊的瀏覽器主要指可以非常迅速地對這些事件作出回應,所以我們需要限制回調,以確保它不能在毫秒內被再一次調用。 你可以在Facebook和Medium上遇到過漸進式圖片,當頁面滾動到視圖時,模糊的低分辨率圖像會被清晰的全分辨率版本替換。 showImg(htt...
摘要:小蘿卜滬江前端開發(fā)工程師本文原創(chuàng)翻譯,有不當?shù)牡胤綒g迎指出。簡稱就非常擅長做這些,事實這也是它們的宗旨。通過它精心設計的規(guī)則能保證優(yōu)先顯示頁面的主要內容。原創(chuàng)新書移動前端高效開發(fā)實戰(zhàn)已在亞馬遜京東當當開售。 小蘿卜(滬江前端開發(fā)工程師)本文原創(chuàng)翻譯,有不當?shù)牡胤綒g迎指出。轉載請指明出處。 如果你在過去幾個月一直關注web開發(fā)社區(qū),你很可能已經(jīng)閱讀了 progressive web ap...
摘要:原文鏈接原作者利用原生方法替換實現(xiàn)性能提升現(xiàn)在我們正在用實現(xiàn)一個具有郵件收發(fā)和即時聊天功能的客戶端工具。為了防止用戶感覺卡頓,所有的動作都需要在毫秒級完成。然而理想是豐滿的,現(xiàn)實是殘酷的。。。 原文鏈接 https://medium.com/missive-ap...原作者Philippe Lehoux 利用js原生方法替換react component實現(xiàn)性能提升 現(xiàn)在我們正在用Re...
閱讀 2812·2021-10-11 10:57
閱讀 2411·2021-08-27 16:20
閱讀 1391·2019-08-30 13:03
閱讀 1566·2019-08-30 12:50
閱讀 3343·2019-08-29 14:16
閱讀 1564·2019-08-29 11:12
閱讀 1616·2019-08-28 17:53
閱讀 2897·2019-08-27 10:58