具代表性的面試主題

前端面試:如何用 interestfor 建立漸進增強的預覽浮層?

前端困難
Offer.cc 編輯團隊發佈 更新

題幹

你要為使用者頭像做預覽浮層:滑鼠懸停、鍵盤聚焦或觸控長按時顯示,離開興趣範圍後隱藏。請說明如何使用 interestfor,並處理相容性、焦點、延遲及不應由懸停觸發的內容。

題幹與適用場景

你要為使用者頭像做預覽浮層:滑鼠懸停、鍵盤聚焦或觸控長按時顯示,離開興趣範圍後隱藏。請說明如何使用 interestfor,並處理相容性、焦點、延遲及不應由懸停觸發的內容。

Popover API 的 interest invoker 讓按鈕或連結透過 interestfor 指向同一文件樹中的目標 ID。目標可以是 popover="hint" 的預覽卡,瀏覽器在懸停、聚焦或長按等產生興趣時顯示,興趣結束時隱藏。它適合非關鍵、短暫的輔助資訊,不應成為唯一資訊或操作入口。

面試官考察點

面試官會關注你是否區分興趣觸發與啟用觸發,是否理解目標 ID、Popover 狀態和 InterestEvent,能否處理鍵盤、觸控、延遲、相容性及可存取性,並能說明何時應改用明確點擊或普通連結。

回答前需要釐清的問題

先確認浮層是提示、預覽還是包含可操作控制項的選單;確認支援的瀏覽器、是否需要觸控裝置、浮層內容是否關鍵,以及目標是否位於同一 DOM 樹。再確認浮層是否允許進入並停留、顯示和隱藏延遲、焦點返回規則及無 JavaScript 時的最低體驗。

30 秒回答框架

「我會讓原生按鈕或連結用 interestfor 指向 Popover 提示目標,保留可見的頭像名稱和普通連結作為主路徑。interest invoker 負責懸停、聚焦和長按的顯示生命週期;我會用 interest-delay 或等價策略降低抖動。先做特性偵測,舊瀏覽器回退到聚焦與點擊監聽。預覽資訊不能只存在浮層,鍵盤和觸控都要可用,帶操作的內容則改用明確啟用。」

分步驟深入解答

第一步:建立興趣觸發關係

interestfor 的值指向目標元素的 ID,目標與觸發器需要在同一棵樹中。最小範例如下:

html
<button interestfor="profile-preview" aria-label="查看 Ada 的簡介">
  Ada Lovelace
</button>
<article id="profile-preview" popover="hint">
  早期電腦科學先驅,簡介內容可在個人頁查看。
</article>

這個按鈕仍是可聚焦的原生控制項;浮層是輔助預覽,不承擔進入個人頁的唯一入口。

第二步:區分興趣與啟用

興趣觸發是暫態回饋,適合預覽、解釋和補充資訊;點擊或按下 Enter 是啟用動作,適合導覽、提交和不可逆操作。不要把刪除、購買或確認等控制項藏在只靠興趣出現的浮層裡。

第三步:保留 Popover 的邊界

popover="hint" 目標由瀏覽器管理顯示狀態。不要同時用另一套腳本強制切換同一屬性,避免原生生命週期和元件狀態互相覆蓋。若浮層需要選單鍵盤模型、焦點陷阱或複雜狀態,應評估對話框、選單元件或明確點擊方案。

第四步:處理顯示延遲與抖動

進入和離開的邊界可能在觸發器與浮層之間快速切換。可以使用 interest-delay 設定顯示與隱藏延遲,並把浮層與觸發區設計成連續的命中區域。延遲應透過真實指標、鍵盤和觸控測試校準,不能假設所有裝置都適合固定數字。

第五步:涵蓋鍵盤與讀屏路徑

原生按鈕或連結可取得焦點,浮層出現時應有清楚的名稱關係,且焦點不應被意外搶走。預覽文字必須能透過可見名稱、連結目標或其他靜態內容取得;不要用懸停狀態取代焦點指示,也不要把重要錯誤只放在浮層中。

第六步:考慮觸控與長按

觸控沒有傳統 hover。interest invoker 的長按行為可提供預覽,但不應阻斷正常點擊或捲動。對關鍵動作保留明確的 tap 入口,並在小螢幕上檢查浮層是否遮擋內容、超出視窗或無法關閉。

第七步:做特性偵測與降級

不能假設所有執行環境都支援 interestfor。可檢測 HTMLButtonElement.prototype.interestForElement;不支援時保留普通 HTML 內容和連結,再用同一業務狀態的 focus、pointer 或 click 監聽提供基礎預覽。降級程式碼只補能力,不重複渲染另一份事實。

第八步:驗證生命週期與邊界

測試滑鼠進入、移出、從觸發器移到浮層、Tab 聚焦、Shift+Tab、觸控長按、捲動、Escape、快速重複進入以及目標動態卸載。驗證無障礙樹、浮層邊界、延遲、無 JavaScript 內容和瀏覽器相容矩陣;MDN 的可用性標籤不能取代專案目標瀏覽器的實測。

高品質示範回答

我會把頭像做成原生連結或按鈕,用 interestfor 指向同一棵樹中的 popover="hint" 預覽卡。預覽只提供補充資訊,頭像名稱和個人頁連結在靜態內容中始終可見。興趣生命週期涵蓋滑鼠、焦點和長按;我會用 interest-delay 降低抖動,並讓觸發器到浮層之間的命中區域連續。實作前檢測 interestForElement,不支援時保留普通內容並用同一處理邏輯補充 focus、pointer 或 click。對刪除、購買、選單等帶副作用或需要完整鍵盤模型的內容,使用明確啟用元件,不把關鍵操作放在興趣浮層裡。最後用鍵盤、觸控、讀屏、捲動、Escape、動態卸載和目標瀏覽器矩陣驗收。

常見錯誤

把 interestfor 當成任意元素的通用 tooltip 屬性

它建立的是興趣觸發器到目標的關係,並依賴 Popover 及相關瀏覽器能力。若目標不是合適的浮層語義,或需要複雜選單狀態,應採用對應元件模型。

只寫 hover CSS,忽略焦點和觸控

鍵盤使用者沒有滑鼠 hover,觸控也沒有相同的指標軌跡。必須保留焦點路徑、tap 入口和靜態可見資訊。

讓浮層承載唯一關鍵內容

使用者可能使用不支援該屬性的瀏覽器、關閉腳本或無法完成長按。關鍵名稱、狀態和操作應在主內容或明確啟用路徑中取得。

延伸追問與參考答案

不支援 interestfor 的瀏覽器怎麼辦?

先保證普通 HTML、連結和焦點樣式完整,再做特性偵測。降級監聽只補充預覽,不改變主導覽和資訊結構,並在相容矩陣中驗證。

如何避免觸發器與浮層之間閃爍?

讓命中區域連續,使用顯示和隱藏延遲,並在移入目標後保持興趣。不要用多個腳本同時控制 Popover 狀態;必要時記錄進入、離開和卸載順序。

鍵盤聚焦時應該把焦點移入浮層嗎?

純預覽通常不搶焦點,保持觸發器焦點並提供可感知名稱。若浮層包含可操作內容,應改用明確啟用的選單或對話框模型,定義進入、Escape 和返回規則。

如何處理觸控長按與點擊衝突?

長按預覽不能阻斷 tap 導覽或捲動。為關鍵動作保留 tap 目標,並在真實裝置上驗證長按、短按、捲動和視窗邊界。

interest-delay 應該設定多少?

沒有跨裝置通用的固定值。根據內容密度和誤觸成本測量進入、離開和快速移動場景,同時提供立即聚焦回饋,避免延遲讓鍵盤使用者等待。

什麼時候不該使用 interest invoker?

當內容關鍵、操作有副作用、需要複雜焦點管理、需要跨樹協調或必須覆蓋舊瀏覽器時,應使用靜態內容加明確啟用的元件。interest invoker 更適合低風險、暫態的輔助預覽。

公開來源

同類題目