成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【譯】漸進(jìn)增強(qiáng)的鍵盤導(dǎo)航

Juven / 1587人閱讀

摘要:鍵盤訪問(wèn)的升級(jí)提供快捷方式不過(guò),在訪問(wèn)網(wǎng)格時(shí),通過(guò)鍵盤進(jìn)行兩個(gè)方向的移動(dòng)會(huì)不會(huì)更好呢使用一點(diǎn)做漸進(jìn)增強(qiáng),我們做到了,可以使用鼠標(biāo)或方向鍵訪問(wèn)網(wǎng)格。在本例總共,查找表名字是。

厚著臉做推廣,個(gè)人網(wǎng)站 http://www.wemlion.com/。

本文轉(zhuǎn)載自:眾成翻譯
譯者:文藺
鏈接:http://www.zcfy.cc/article/1179
原文:https://www.christianheilmann.com/2016/08/15/better-keyboard-navigation-with-progressive-enhancement/

創(chuàng)建界面時(shí)很重要的一點(diǎn)是,要考慮到那些只依賴鍵盤來(lái)使用產(chǎn)品的用戶。這對(duì)可訪問(wèn)性來(lái)說(shuō)是基本要求,在多數(shù)情況下,通過(guò)鍵盤操作訪問(wèn)也并非難事。這意味著首先,也是最重要的,是使用鍵盤可訪問(wèn)元素進(jìn)行交互。

如果希望用戶跳轉(zhuǎn)到其他地方,使用帶有有效的 href 屬性的錨點(diǎn)連接

如果希望用戶執(zhí)行你自己的代碼,并在當(dāng)前文檔中停留,使用按鈕

通過(guò)流動(dòng) tabIndex 技術(shù)幾乎可以使所有內(nèi)容都能通過(guò)鍵盤訪問(wèn),不過(guò),既然已經(jīng)有 HTML 元素可以做同樣的事情,又何必再麻煩呢。

效果可視化

不過(guò),使用恰當(dāng)?shù)脑夭⒉荒敲春?jiǎn)單;用戶鍵盤在元素集合中所處的位置,也要顯眼一些。給激活的元素加上輪廓(outline),瀏覽器解決了這個(gè)問(wèn)題。這雖然超有用,但卻是一些人的眼中釘,他們希望由自己控制所有交互的視覺展現(xiàn)。在 CSS 中將 outline 屬性設(shè)置為 none,就能移除這個(gè)視覺輔助功能;不過(guò)這會(huì)帶來(lái)不小的可訪問(wèn)性問(wèn)題,除非你提供一個(gè)別的替代。

使用最顯眼的 HTML 元素;加上一些 CSS,確保除 hover 之外 focus 狀態(tài)同樣也被定義。這樣就可以使用戶在列表中的一個(gè)個(gè)項(xiàng)目間,輕松地通過(guò) tab 來(lái)切換了。Shift + Tab 允許回退。可以看下 demo,HTML 挺簡(jiǎn)單粗暴的。

使用列表,為我們的元素賦予了層次結(jié)構(gòu),以及普通瀏覽器所沒(méi)有的可訪問(wèn)性技術(shù)的導(dǎo)航方式。它還帶來(lái)很多 HTML 元素,我們可以自己添加樣式。通過(guò)一點(diǎn)樣式,我們可以將其轉(zhuǎn)換為網(wǎng)格,占用更少的垂直空間,容納更多內(nèi)容。

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);
}

結(jié)果看起來(lái)非常棒,在查看列表的過(guò)程中,我們能清楚地看到自己所處的位置。

鍵盤訪問(wèn)的升級(jí) —— 提供快捷方式

不過(guò),在訪問(wèn)網(wǎng)格時(shí),通過(guò)鍵盤進(jìn)行兩個(gè)方向的移動(dòng)會(huì)不會(huì)更好呢?

使用一點(diǎn) JavaScript 做漸進(jìn)增強(qiáng),我們做到了,可以使用鼠標(biāo)或方向鍵訪問(wèn)網(wǎng)格。

不過(guò)記著,這僅僅只是一個(gè)增強(qiáng)。假設(shè) JavaScript 因?yàn)楦鞣N可能的原因執(zhí)行失敗,依然可以通過(guò) tab 來(lái)訪問(wèn)列表,我們失去的只是便利,但至少還有可用的界面。

我將這個(gè)打包成了一個(gè)小巧、無(wú)依賴的開源 JavaScript 項(xiàng)目 gridnav,可以在 GitHub 上獲取代碼。你要做的就是調(diào)用腳本,傳給它一個(gè)選擇器以獲取元素列表。




 

通過(guò)列表元素的 data- 屬性,可以自己定義每行元素的數(shù)量以及鍵盤可訪問(wèn)的元素。這些是可選的,但設(shè)置之后會(huì)讓代碼更快,出錯(cuò)可能性更小。README 文件更詳細(xì)地解釋了如何使用。

工作原理

開始考慮如何做的時(shí)候,像任何開發(fā)者一樣,抓到了最復(fù)雜的方式。我以為,需要對(duì)父節(jié)點(diǎn)、兄弟節(jié)點(diǎn)的大量定位比較,使用上 getBoundingClientRect,進(jìn)行大量的 DOM 訪問(wèn)。

之后我往回走了一步,意識(shí)到如何展示列表并不重要。最終不過(guò)是一個(gè)列表,我們要訪問(wèn)它而已。甚至不需要訪問(wèn) DOM,因?yàn)槲覀兯龅牟贿^(guò)是從一堆按鈕或錨點(diǎn)連接中的一個(gè)切換到另一個(gè)。我們要做的就是:

找到當(dāng)前所在元素(event.target)。

獲取按下的鍵。

根據(jù)鍵向前向后移動(dòng),或跳過(guò)一些元素到下一行。

就像這樣(點(diǎn)擊這里試試看):

我們需要跳過(guò)的元素?cái)?shù)量是由每行的元素?cái)?shù)量決定的。向上等同于向前 n 個(gè)元素,向下相當(dāng)于向后 n 個(gè)元素。

使用一些小技巧,完整代碼非常簡(jiǎ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ā)生了什么?

首先我們獲取到了列表元素,并緩存所有可通過(guò)鍵盤訪問(wèn)的元素:

  var list = document.querySelector("ul");
  var items = list.querySelectorAll("button");

計(jì)算每次上下移動(dòng)需要跳過(guò)的元素?cái)?shù)量,將列表的寬度除以列表第一個(gè)子元素(本例中是 LI)的寬度即可:

  var amount = Math.floor(
        list.offsetWidth / list.firstElementChild.offsetWidth
      );

相較于 switch 語(yǔ)句或者大量的 if 判斷,我更樂(lè)意使用查找表。在本例總共,查找表名字是 codes。向上鍵值為 38,向下 40,向左 37,向右 39。假如我們拿到了 codes[37],值為 -1,也就是我們要在列表中移動(dòng)的數(shù)量:

  var codes = {
    38: -amount,
    40: amount,
    39: 1,
    37: -1
  };

可以使用 event.target 獲取按下鍵盤時(shí)列表中的選中元素,但我們不知道它在列表中的位置。為避免重復(fù)遍歷列表,一次性遍歷所有按鈕,將它們?cè)诹斜碇械乃饕鎯?chǔ)在按鈕自身的 index 屬性中。

  for (var i = 0; i < items.length; i++) {
    items[i].index = i;
  }

handlekeys() 完成剩余工作。讀取所按按鍵的鍵值,然后到 codes 中查找。所以,我們只針對(duì)方向鍵做出響應(yīng)。接著獲取當(dāng)前的元素,檢查其是否有 index 屬性。如果有,則檢查我們將要移到的位置是否有元素存在。如果元素存在,則獲得焦點(diǎn)。

  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();
        }
      }
    }
  }

給列表綁定一個(gè) keyup 事件監(jiān)聽器,搞定 :)

  list.addEventListener("keyup", handlekeys);

如果你想看真實(shí)效果,這有一個(gè)講述各個(gè)細(xì)節(jié)的快速視頻教程。

視頻在最后的代碼部分有點(diǎn) bug,因?yàn)槲覜](méi)將 count 屬性和 undefined 對(duì)比,所以在第一個(gè)元素上,鍵盤功能沒(méi)法正常工作(0 是 falsy)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/111492.html

相關(guān)文章

  • 關(guān)于響應(yīng)式設(shè)計(jì)一些關(guān)鍵點(diǎn)

    摘要:這里使用到的最多的中的屬性,即媒體查詢響應(yīng)式設(shè)計(jì)實(shí)踐原則漸進(jìn)增強(qiáng)漸進(jìn)增強(qiáng)英語(yǔ)是網(wǎng)頁(yè)設(shè)計(jì)的一種策略,強(qiáng)調(diào)可訪問(wèn)性,語(yǔ)義標(biāo)記,外部樣式表和腳本技術(shù)。 1、響應(yīng)式設(shè)計(jì)關(guān)鍵點(diǎn)在于: 媒體查詢、流動(dòng)網(wǎng)格、彈性圖片,而不是flex布局或者是自適應(yīng)布局 響應(yīng)式和自適應(yīng)的最直觀的區(qū)別是:自適應(yīng)是為了解決如何才能在不同大小的設(shè)備上呈現(xiàn)同樣的網(wǎng)頁(yè),直觀地來(lái)看就是盒子會(huì)根據(jù)屏幕分辨率的大小進(jìn)行伸縮變換。所以...

    golden_hamster 評(píng)論0 收藏0
  • JavaScript 基礎(chǔ)知識(shí) - DOM篇(一)

    摘要:前言本篇文章是基礎(chǔ)知識(shí)的篇,如果前面的基礎(chǔ)知識(shí)入門篇看完了,現(xiàn)在就可以學(xué)習(xí)了?;靖拍罘譃槿齻€(gè)部分。在這個(gè)基礎(chǔ)上使用一些新特性,高級(jí)瀏覽器支持,低級(jí)瀏覽器不支持。在對(duì)象中的屬性是一個(gè)布爾值,只有和。 showImg(https://segmentfault.com/img/remote/1460000012581493?w=1920&h=1080); DOM 前言 本篇文章是JavaS...

    cuieney 評(píng)論0 收藏0
  • []如何構(gòu)建自己Progressive Image Loader

    摘要:最后,我們必須調(diào)用函數(shù)來(lái)檢查所有的漸進(jìn)式圖片容器在首次運(yùn)行時(shí)是否在頁(yè)面上可見。我們還必須在滾動(dòng)頁(yè)面或調(diào)整瀏覽器大小時(shí)調(diào)用函數(shù),在一些舊的瀏覽器主要指可以非常迅速地對(duì)這些事件作出回應(yīng),所以我們需要限制回調(diào),以確保它不能在毫秒內(nèi)被再一次調(diào)用。 你可以在Facebook和Medium上遇到過(guò)漸進(jìn)式圖片,當(dāng)頁(yè)面滾動(dòng)到視圖時(shí),模糊的低分辨率圖像會(huì)被清晰的全分辨率版本替換。 showImg(htt...

    cartoon 評(píng)論0 收藏0
  • | Progressive Web AMPs

    摘要:小蘿卜滬江前端開發(fā)工程師本文原創(chuàng)翻譯,有不當(dāng)?shù)牡胤綒g迎指出。簡(jiǎn)稱就非常擅長(zhǎng)做這些,事實(shí)這也是它們的宗旨。通過(guò)它精心設(shè)計(jì)的規(guī)則能保證優(yōu)先顯示頁(yè)面的主要內(nèi)容。原創(chuàng)新書移動(dòng)前端高效開發(fā)實(shí)戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開售。 小蘿卜(滬江前端開發(fā)工程師)本文原創(chuàng)翻譯,有不當(dāng)?shù)牡胤綒g迎指出。轉(zhuǎn)載請(qǐng)指明出處。 如果你在過(guò)去幾個(gè)月一直關(guān)注web開發(fā)社區(qū),你很可能已經(jīng)閱讀了 progressive web ap...

    miracledan 評(píng)論0 收藏0
  • 】利用js原生方法替換react component實(shí)現(xiàn)性能提升

    摘要:原文鏈接原作者利用原生方法替換實(shí)現(xiàn)性能提升現(xiàn)在我們正在用實(shí)現(xiàn)一個(gè)具有郵件收發(fā)和即時(shí)聊天功能的客戶端工具。為了防止用戶感覺卡頓,所有的動(dòng)作都需要在毫秒級(jí)完成。然而理想是豐滿的,現(xiàn)實(shí)是殘酷的。。。 原文鏈接 https://medium.com/missive-ap...原作者Philippe Lehoux 利用js原生方法替換react component實(shí)現(xiàn)性能提升 現(xiàn)在我們正在用Re...

    piapia 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<