﻿# 前端工程研究：如何將鍵盤焦點設定在一個無法 focus 的 DIV 元素上

在我們公司所有的專案都在 Azure DevOps Services 上面管理，從專案管理、原始碼版控、CI/CD、文件管理、測試管理、專案報表等等，都在 Azure DevOps Services 上面，所以我們的團隊成員每天都會花很多時間在 Azure DevOps Services 上面協作。雖然 Azure DevOps Services 也提供了很多鍵盤快速鍵，讓使用者可以更快速的操作，但還是沒辦法滿足我們的需求，所以這個假日我就打算在寫一個 Side Project 擴充更多鍵盤快速鍵。原本以為一個小時內可以完成的，結果卻卡關在一個不起眼的功能上，那就是 DIV 元素無法被 focus 的問題，這會導致你將無法透過鍵盤的「空白鍵」來捲動頁面，我為了提升這個小小的 UX 問題，花了好幾個小時才找到答案，這篇文章就來跟大家分享一下我研究出來的解法。

![](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/d5f1fa72ee7d4061f060-97234cbf-f151-403d-82af-f261b2174245.webp)

### 先看看我遇到的問題

直接看影片吧，注意用鍵盤的「空白鍵」可以將頁面的內容向下或向上捲動：

<iframe title="YouTube video player" src="https://www.youtube.com/embed/0lRpyQh5B3U?si=hS6mJIeFZgicPy7L" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe>

### 為什麼控制鍵盤焦點很重要

網站的**可及性**(Accessibility)其實很多開發者都不太重視，其中一個常見的需求，就是網站瀏覽需要有可替代的「鍵盤操作」能力，也就是說你不能只透過「滑鼠」去操作整個網站，所有功能也都要能透過「鍵盤」來使用。

當然，這樣的需求主要是針對「身心障礙者」所提供，但其實就算你不是「身心障礙者」其實也可能需要這樣的功能。以我個人為例，我對於常用的軟體或網站，都會盡可能的透過「鍵盤」來操作功能，所以會自訂許多快速鍵，以提升電腦的操作效率。

話說回來，其實 Azure DevOps Services 的可及性設計已經非常優秀，內建的「快速鍵」也已經非常多，你只要在 Azure DevOps Services 的任何頁面按下 `?` 符號 (`Shift + /`)，就會出現快速鍵的說明，如下圖所示：

![Keyboard shortcuts for Azure DevOps](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/fac757af25683268b333-73271e42-1bd2-4dde-bdf2-c76336e44c54.jpg)

> 詳見[完整的 Azure DevOps Services 快速鍵清單](https://learn.microsoft.com/en-us/azure/devops/project/navigation/keyboard-shortcuts?view=azure-devops&WT.mc_id=DT-MVP-4015686) (Keyboard shortcuts for Azure DevOps and Team Explorer)

### 控制鍵盤焦點所遇到的問題

由於我們長久以來會面臨到的 HTML 元素的 focus 問題，通常都只是需要對焦在 `INPUT` 或 `TEXTAREA` 這種輸入欄位上而已，這種表單欄位的 Element (元素) 呼叫 `.focus()` 方法其實不太有什麼問題，也很少會遇到什麼地雷。

我這次的需求則是需要讓「鍵盤」的焦點停留在一個有設定「捲軸」的`DIV` 元素上，這個問題有很困難嗎？我一直以為「所有的元素」幾乎都有 `.focus()` 方法可以呼叫，也都有 `focus` 事件可以訂閱，但實則不然，其實大部分「非表單欄位」的元素，都是無法呼叫 `.focus()` 方法的，或者更精準一點來講：就算呼叫了 `.focus()` 方法，也不會有任何效果。

回想一下，一般來說我們都是如何控制網頁上的「鍵盤」焦點的？我都是用「滑鼠」在頁面上的「空白處」點擊一下，鍵盤的焦點就會跑到該區域，然後你就可以用「鍵盤」的「空白鍵」來控制頁面的瀏覽，按下 `Space` 鍵就會往下捲動，按下 `Shift + Space` 鍵就會往上捲動。

問題來了，這個「點一下」的動作，要怎樣寫成 JavaScript 呢？我發現我連「提問」的能力都沒有，我嘗試了 30 分鐘，問了 ChatGPT 無數個問題，通通找不到我的答案，因為我不知道該怎麼問才夠精準，精準到 AI 可以告訴我答案。如果是你，你會怎樣提問？

重點來了，你知道我是怎樣找出解決方案的嗎？我問了 [Stack Overflow](https://stackoverflow.com/) 的 [OverflowAI Search](https://stackoverflow.com/ai-assist) 功能！

![OverflowAI Search](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/723f5a7137c44f6b5d93-f80562d7-e589-4d59-8900-697a0a61d8bf.jpg)

真的不誇張，一次提問就讓我找到答案，精準度與正確性都完勝 ChatGPT，而且還有 Stack Overflow 上面的完整參考資料！

我的提問內容是：

> There are many scrollable area in a web page. When I use the mouse to click on a scrollable DIV on a web page, I can hit Space key to scroll down on that part of a HTML page. When focus lost, I can't hit Space key to scroll on that area. What if I want to get focus again to that area so that I can let user hit Space key to scroll. What can I do using JS?

不過，其實 OverflowAI Search 的回答是錯誤的，但正確答案在參考的資訊來源中！👍

![OverflowAI Search - Answers](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/bcf4563eb69c2df755f9-64f0273a-3b86-4784-9e03-c86d63c420c2.jpg)

### 設定在一個無法 focus 的 <div> 元素上

答案在此：[javascript - Set keyboard focus to a <div> - Stack Overflow](https://stackoverflow.com/a/6809236/910074)

基本上，要讓 `div` 元素可以被聚焦，必須有以下條件：

1.  只要將 `div` 元素加上 `tabindex` 屬性即可

就這樣，就這麼簡單！👍

若你不想讓使用者因為按下 `Tab` 鍵會移動鍵盤定位在這個 DIV 上面，你可以將 `tabindex` 屬性設定為 `-1`，這樣就不會被鍵盤定位到了。

### 相關連結

-   [Making Elements Focusable with Tabindex - Snook.ca](https://snook.ca/archives/accessibility_and_usability/elements_focusable_with_tabindex)
