Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 青青免费视频精品一区二区,久久国产精品一区,激性欧美激情在线播放16页

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          為知乎增加快捷鍵

          近,知乎在桌面端網頁上陸續增加了一些快捷鍵:

          • 在首頁、個人頁和搜索結果頁等頁面瀏覽時[1]:按 J、K 來選中列表中的條目,按 O 來展開或收起全文,按 V、D 來贊同與反對等。另外,按 Esc 也可以退出大部分彈窗與彈出式菜單。
          • 在播放視頻時:按 F 讓播放器全屏,按 M 讓視頻靜音,按數字 0-9 可以跳轉到對應的視頻進度(0%-90%)等。
          • 在回答與文章的編輯器中也有一些快捷鍵:比如按 ?+K 可以插入鏈接等。把光標移動到工具欄中的按鈕上可以查看介紹。

          在非輸入狀態下按 ?(Shift+/)就可以查看快捷鍵列表

          在開發快捷鍵的過程中,有一些值得分享的經驗。

          開發快捷鍵

          快捷鍵的作用域

          實現快捷鍵不困難,因為監聽鍵盤事件很簡單。大部分時候,我們只需要在希望響應事件的最外層元素上注冊事件就行,而響應事件的回調(比如關閉模態框)也都可以在這個最外層組件內實現。

          知乎首頁的組件結構

          但是這次的情況要更加復雜。以在首頁按 V 贊同答案為例:列表內的時間線條目(FeedItem)包括了回答(AnswerItem)在內各種類型的內容,而在回答里的贊同按鈕(VoteButton)才是適合響應快捷鍵事件的地方。在最外側的 FeedItem 上容易注冊事件卻無法響應事件,在最內側的 VoteButton 中可以響應事件卻不能簡單地注冊事件。

          如何在 React 的組件關系中優雅地實現子組件(贊同、收藏按鈕等)注冊快捷鍵和回調函數、同時直到父組件(整個回答甚至 Feed 條目)的范圍內都可以響應快捷鍵是比較有趣的。

          一種簡單的想法是:放棄在子組件中注冊快捷鍵,全部在父組件中注冊快捷鍵,在回調的時候調用子組件的實例方法。這會造成以下這些問題:

          • 幾乎放棄了組件的層級抽象:從外向里調用子組件實例方法比較 anti-pattern、難以管理(更別提在 React 中,越過接入 connect 等函數的 HOC 來獲取真正的組件實例了)。
          • 快捷鍵會被重復定義和實現:比如在想法、文章和答案等所有引用贊同按鈕的父組件中,都注冊和實現同樣的按 V 贊同的快捷鍵。
          • 在知乎的組件結構中,這種實現最多只能在位于層級中部的 AnswerItem 范圍內進行,因為 FeedItem 的實現不關心子組件內部的業務。

          現在知乎使用的方案是:基于 React context 來為所有子組件共享一個「快捷鍵實例」,在這個「作用域」下的所有子組件聲明快捷鍵時,都會注冊到這個實例上面。

          參考下方的偽代碼:

          function FeedItem() {
            const feedItemElement = useRef(null)
            return (
              <ShortcutContext value={feedItemElement}>
                <div className="FeedItem" ref={feedItemElement}>
                  <AnswerItem />
                </div>
              </ShortcutContext>
            )
          }

          在 FeedItem 中,以自身的 HTML element 來初始化一個新的快捷鍵實例并設置在 context 中,實際的 keydown 等鍵盤事件是注冊在這個 element 上。所以子組件都可以通過 context 在這個實例上注冊新的快捷鍵。

          function VoteButton() {
            const handleVote = () => console.log('voting')
            // 在 useShortcut 中查找當前 context 中存在的快捷鍵實例,并注冊在實例上
            useShortcut('v', handleVote)
            return <button onClick={handleVote}>贊同</button>
          }

          在 VoteButton 中,就可以像響應點擊事件一樣注冊并響應快捷鍵事件,看起來和寫起來都非常清爽。

          列表導航的快捷鍵

          使用 J、K 進行 Vim 風格的列表導航是許多網站常見的快捷鍵設計[2]。下面是一些如果從零開始實現時,可能會遇到的細節問題:

          • 直接使用 element.focus() 方法會由瀏覽器決定一個合適的滾動位置,這通常是不符合預期的(對于知乎來說,是因為頂部有一個固定的導航欄,原生滾動經常會被這個導航欄擋住)。我們使用 preventScroll: true 參數禁用了這個原生的滾動,并使用自己計算的結果來 window.scrollTo() 到指定位置。
          • 不是所有元素都是可以被 focus 的。如果只是普通的 <div> 元素的話,可以設置 tabIndex 為 0 或 -1 使其可被 focus。如果設置為 -1 的話則只可以被 focus,但是不能被 Tab 鍵選中[3]。是否希望被 Tab 選中,主要在于該元素內是否有可以被閱讀的元素,或者該元素本身有可交互的行為。
          • 如果在 focus 到某個列表元素后,又用滾輪或者觸摸板移動了網頁到很遠的距離,再按 J、K 進行導航時就需要放棄已經 focus 的元素的,盡可能地 focus 在視圖區域內可見的元素上[4],或者采用別的策略[5]
          • 和其他類似產品不同,知乎大部分列表元素不是整個區域都可以點擊并進入詳情頁,而是鼓勵在當前頁面展開并消費內容的(否則可以直接使用一個 <a> 標簽包裹。這次特意實現了 focus 在列表項時,按 Enter 鍵可以進入詳情頁的快捷鍵。
          • 如果因為點擊而 focus 在某個列表項時(比如第 2 項),按 J、K 導航時最好只是先在該元素上顯示 focus outline,而不是直接進行快捷鍵導航(到第 1 項或者第 3 項)。因為此時用戶不一定知道自己已經 focus 在這個列表項上。這和知乎不為點擊行為導致的 focus 添加 outline 有關。

          Focus Outline 該在什么時候展現

          當使用快捷鍵進行瀏覽時,「知道光標在哪里」很重要。屏幕閱讀器可以閱讀當前 focus 元素的內容。如果不通過聲音的話、就只能通過視覺樣式來知道當前正在 focus 的元素是什么。

          Chrome 為 Input 標簽默認添加的 focus outline

          瀏覽器默認會為可 focus 的元素通過 :focus 偽類增加一個 outline 樣式,因為這個樣式不是很好看,再加上可 focus 的元素往往也會單獨設計一些響應點擊的樣式,所以一般產品或設計會要求工程師取消掉該樣式。但是如果簡單取消所有 focus 樣式后,用鼠標當然知道「我在點哪里」,但在使用鍵盤訪問的場合就根本不知道「我在哪里」了。

          最優雅的方案是使用 CSSWG 的 :focus-visible 偽類來添加 focus 樣式(同時禁用原先的 :focus 樣式),在 WICG 對該樣式的 polyfill 中有詳細的介紹。簡單來說,就是「只有用鍵盤觸發的 focus 才應該添加 focus 樣式」。

          知乎按鈕的 focus 樣式

          知乎通過和該 polyfill 類似的思想實現了這一設計:在使用鍵盤操作后,會為 <html> 元素添加 data-focus-visible 屬性。只有在包含該屬性的情況下,各個元素才會添加 focus 樣式。而且知乎還修改了默認的樣式、更為美觀。你可以使用 Tab 鍵 tab 到贊同按鈕上查看這個效果。

          在開發這一部分功能的時候,還有一個特殊的設計:使用 ?+C 等快捷鍵進行復制粘貼操作(準確地說,是按鍵中包括 Control 或 Shift 等 Modifier Key)時,不認為是一般的鍵盤操作,也不展現 focus outline,否則 outline 會過于頻繁地時有時無。有意思的是,Twitter 其實也已經做了類似的處理,讓人感到大洋兩岸的工程師都在為用戶體驗而努力…

          快捷鍵和可訪問性的關系

          很多關于快捷鍵的討論都會有視障用戶的參與,因為使用屏幕閱讀器瀏覽網頁、必須使用包括 Tab 鍵在內的各種鍵盤快捷鍵進行光標定位與操作,他們是「最會用鍵盤刷知乎」的人。但是,對視障用戶的支持遠不止添加快捷鍵這么簡單。


          @devil纏

          在一個答案的評論區[6]提到:

          如果只是單個按鍵,(快捷鍵)基本上沒有任何用處。以 V 為例:當用 Tab 到達「贊同」按鈕時,直接(按)空格就可以點贊同。(另外)如果在查看內容區點擊 V,焦點不會跑到「贊同」按鈕上。

          合理的快捷鍵有可能用處不大,而不合理的快捷鍵不但不能幫助視障用戶,還會幫倒忙。

          @殷曉波

          @devil纏

          都提到「使用 V 贊同之后,希望可以 focus 到贊同按鈕」,如果不真正使用屏幕閱讀器瀏覽網頁,是無法想象這句話的原因的:

          快捷鍵贊同后,需要轉移焦點

          簡單來說,屏幕閱讀器只有在焦點改變時才會閱讀焦點內的文字,它監控不到「贊同按鈕變深藍」這樣普通人可以輕松理解的設計反饋。如果使用快捷鍵贊同后不改變焦點,連按下鍵盤發生了什么都不知道,也就不會知道「已經贊同了答案」。此時 tab 到贊同按鈕上閱讀到「已贊同」的文字才知道發生了什么就很奇怪。

          瀏覽器的點擊行為會自動 focus 在可交互的元素上(例如 <button><a>),而此時按 Enter 或 Space 等快捷鍵可以「模擬一次點擊」,這套現成的體系很容易被忽略。在實際體驗中,tab 到「閱讀全文」按鈕再按 Space 來展開全文并不比用快捷鍵 O 來展開全文麻煩很多。

          除此之外,很多讀屏軟件或者視障用戶也會定義、開發個性化的快捷鍵[6]。這么來看,使用 <button> 等語義化標簽使元素可交互元素也可以被 focus、盡可能使用 <a> 而不是在監聽 onClick 事件時使用 location.href 進行頁面跳轉、配置好 aria 屬性等…對 Accessibility 更有意義。

          總的來說,實現快捷鍵和實現其他功能一樣也要注意視障用戶的使用、交互體驗,比如:

          • 任何快捷鍵操作后都要像點擊一樣轉移焦點。
          • 轉移焦點后,還需要配置 aria-label 等屬性來閱讀出有意義的提示文字,比如贊同還是已贊同、反對還是已反對。

          快捷鍵只是 Accessibility 的一部分,而可訪問性又是一個更加系統和復雜的工程。知乎做了一些努力[7],但還遠遠不夠。也歡迎對這個領域有更多了解的朋友提出建議。

          Q & A

          可以關閉快捷鍵嗎?

          是的。如果你使用 Vimperator 或者 Vimium 等瀏覽器擴展定制了快捷鍵而不想和知乎的沖突,可以在桌面端網頁的個人偏好設置(https://www.zhihu.com/settings/preference)中關閉快捷鍵[8]

          這篇文章的注釋與參考是如何做到的?

          這是編輯器的新功能,會在開放后再行介紹。

          參考

          ^這些快捷鍵在遷移到新版 Web 頁面時沒有同步遷移,在很長一段時間內都沒有實現。

          ^包括 Twitter、Facebook、Gmail 與新浪微博等,知乎從這些網站的實現細節中受益良多。

          ^一個叫 tabbable 的庫中有關于這兩者區別的介紹,這個庫在實現 focus trap 等效果時很有用。 https://github.com/davidtheclark/tabbable

          ^如何高效地查找離視窗最近、滾動距離最小的元素,這個算法比較有意思,這里不贅述了。

          ^知乎和 Facebook 與新浪微博一樣,會選中視野內可見的新元素,而 Twitter 會放棄滾動。

          ^ab根據 @devil纏 在這個答案評論區中的說法,他使用的讀屏環境還會定義包括 K 下跳 10 個鏈接、Shift+K 上跳 10 個鏈接等快捷鍵 https://www.zhihu.com/question/19842222/answer/17152043

          ^@長天之云 的答案介紹了一些知乎對 a11y 的支持 https://www.zhihu.com/question/20487917/answer/15265930

          ^只在當前使用的瀏覽器中生效。

          作者:孫北吉

          出處:https://zhuanlan.zhihu.com/p/59928288

          在的瀏覽器普遍都支持Javascript,客戶的瀏覽器都安裝了好幾種。這里我們對javascipt做個初步的介紹。

          javascript是一種基于對象和事件并具有安全性能的解釋型腳本語言。不但用于編寫客戶端的腳本程序,由客戶端瀏覽器解釋執行。而且還可以編寫在服務器端執行的腳本程序,由服務器端處理用戶提交的信息并動態地向瀏覽器返回處理結果。



          一、Javascript 數據類型

          字符串型:使用單引號或者雙引號括起來的一個或者多個字符串
          數值型:包括整數或者浮點數(包含小數點的數或者科學計數法的數)
          布爾型:true或者false
          對象型:用于指定javascript程序中用到的對象
          空值:給一個變量賦值null值來清除變量的內容
          undefined:表示該變量尚未被賦值

          二、Javascript 變量

          1、變量命名的規則

          必須以字母或者下劃線開頭,中間可以是數字、字母或者下劃線。

          變量名不能包含空格或加號、減號等符號。

          變量名嚴格區分大小寫的。大小寫不一樣代表不同的變量。

          變量名不能使用關鍵字。

          關鍵字和java的關鍵字類似。這里不列舉。

          2、聲明和賦值

          var variable; //聲明一個變量
          var variable=10; //聲明并賦值11
          var sum,avg; //聲明多個變量
          var sum=0,avg=10; //聲明多個變量并賦值  

          Javascript的函數和語句和php有相通的地方。這里就不介紹了。

          可以閱讀其他相關教程:https://www.w3school.com.cn/js/index.asp

          三、javascript 事件

          事件是某些動作發生的時候產生的信號,這些事件隨時可以發生。引起事件的發生的動作成為觸發事件。比如鼠標點擊了某個按鈕,用戶在文本框輸入文字都會有對應的觸發事件。

          下面是常見的事件:

          onchange

          HTML 元素已被改變

          onclick

          用戶點擊了 HTML 元素

          onmouseover

          用戶把鼠標移動到 HTML 元素上

          onmouseout

          用戶把鼠標移開 HTML 元素

          onkeydown

          用戶按下鍵盤按鍵

          onload

          瀏覽器已經完成頁面加載

          其他事件可以查看手冊:

          https://www.w3school.com.cn/js/js_events.asp

          https://www.w3school.com.cn/jsref/jsref_events.asp

          https://www.w3school.com.cn/jsref/dom_obj_event.asp

          四、調用Javascript腳本

          1、在html中嵌入javascript腳本

          在html中使用<script>標記就可以嵌入到html中

          <script language="javascript">
          ....
          </script>

          language標記的是設置腳本語言的名稱和版本,也可以不設置該屬性,瀏覽器默認使用javascript腳本預約進行處理。

          2、在網頁中引用Js文件

          不管是在php,還是其他語言上甚至是普通的html頁面上,都可以使用外置的腳本文件來調用javascipt腳本

          <script src="url" language="javascript"></script>

          src的url是js文件的路徑,language的作用和上面的一樣。使用腳本文件不僅可以在html中結合使用,還可以與php動態網頁結合使用。使用外部js文件的優點如下:

          將javascript代碼從網頁中獨立出來,方便代碼閱讀

          一個外部js文件可以同時被多個頁面調用。需要修改代碼,只需要修改js文件的代碼,方便代碼維護。

          通過script不僅可以調用自己服務器的上面的js文件,也可以通過路徑調用其他服務器上的js文件。

          注意:在js文件中,只能包含javascript腳本代碼,不能包含<script>標記和html代碼,不然會產生錯誤。

          在引用js文件的<script>和</script>標記的中間不能有其他的javascript代碼,即使存在了瀏覽器也是會忽略這寫代碼,而只執行js文件中的javascript代碼

          3、頁面中調用自定義函數

          這個就是前面說道的事件,根據事件調用自定義函數。

          <button type="button" onclick="check();"> 提交 </button>

          提交按鈕綁定了一個點擊事件,調用check()函數。


          五、瀏覽器不支持Javscript的問題

          1、開啟瀏覽器對Javascript的支持

          有些瀏覽器是出于安全考慮關閉了對javascript的支持,所以可以直接通過瀏覽器啟用對javascript的支持。

          2、使用注釋符號驗證瀏覽器的支持

          如果用戶不確定自己的瀏覽器是否支持javascript腳本,可以使用html的注釋符號來進行驗證。Html注釋符號“<!--”開始,以“-->”結束。如果此注釋符號里的javascript腳本在不支持javascript的瀏覽器,會把javascript腳本作為注釋而不會顯示在客戶瀏覽器上。

          <script type="text/javascript">
          <!--
          //即使不支持Javascript腳本,用戶也看不到這里面的代碼
          var a={};
          a[“stu”] = null;
          -->
          </script>

          3、使用<noscript>標記驗證瀏覽器的支持

          除了上面的方式,還可以使用<noscript>標記來進行驗證。

          如果瀏覽器支持Javascript腳本,那么瀏覽器會忽略<noscript>...</noscript>標記中間的任何內容,反之不支持會把這標記中間的內容顯示出來。用來提醒瀏覽者當前使用瀏覽器是否支持Javascript腳本。

          文章有
          ctrl+s一鍵提交的功能時候,真的是會方便很多,對于我們這些高度使用pc,并且熟悉PC快捷鍵的使用者來說,如何實現html響應ctrl+s快捷鍵,下面我分享一個簡單的代碼給大家。

          $(window).keydown( function (event) {
                  if(event.ctrlKey  &&  window.event.keyCode==83 ){
                      $("#submit").click()
                      return false
                  }
              }) ;

          當使用ctrl+s組合快捷鍵的時候,我們模擬了submit的點擊事件進行提交文章。


          主站蜘蛛池模板: 日韩精品人妻av一区二区三区| 波多野结衣在线观看一区二区三区| 国产色欲AV一区二区三区| 国产一区二区三区在线观看影院 | 日韩一区二区三区无码影院| 波多野结衣中文字幕一区| 欧美激情国产精品视频一区二区| 精品福利一区二区三| 亚洲高清成人一区二区三区| 国产精品亚洲专一区二区三区| 亚洲日韩中文字幕无码一区| 精品国产一区二区三区不卡| 少妇人妻精品一区二区三区| 国产精品特级毛片一区二区三区| 国产另类ts人妖一区二区三区| 国产伦精品一区二区三区无广告| 成人h动漫精品一区二区无码| 日韩免费一区二区三区在线 | 日韩免费无码一区二区视频| 一区二区三区视频在线观看| 无码少妇一区二区三区浪潮AV| 在线精品亚洲一区二区小说| 一夲道无码人妻精品一区二区| 久久亚洲中文字幕精品一区四| 色狠狠一区二区三区香蕉蜜桃| 国产精品毛片一区二区| 国产伦精品一区二区免费| 久久无码一区二区三区少妇 | 精品一区二区三区电影| 国产一区二区三区不卡在线观看| 国产主播福利精品一区二区| 秋霞鲁丝片一区二区三区| 视频一区二区三区免费观看| 国产精品第一区第27页| 果冻传媒董小宛一区二区| 99精品国产一区二区三区不卡| 亚洲一区免费视频| 日韩成人一区ftp在线播放| 国产激情一区二区三区 | 无码少妇一区二区三区浪潮AV| 国产一区二区三区韩国女主播|