BOM中如何檢測用戶的觸摸屏支持?

觸摸屏檢測需綜合判斷。首先用 navigator.maxtouchpoints 檢查設備是否支持觸摸,其次通過 window.matchmedia(‘(hover: none) and (pointer: coarse)’) 判斷用戶是否主要使用手指交互,最后結合實際觸摸事件動態調整 ui,而非僅依賴 ontouchstart 屬性,因該方式不夠準確且無法反映真實交互意圖。

BOM中如何檢測用戶的觸摸屏支持?

瀏覽器環境中檢測用戶是否支持觸摸屏,并不是一個簡單的“是”或“否”的判斷題,它更像是在收集各種線索,然后根據這些線索來推斷。最核心且相對可靠的線索來自 navigator.maxTouchPoints 和 window.matchMedia 結合的媒體查詢。單一的屬性或事件判斷往往不夠全面,甚至可能誤導。

BOM中如何檢測用戶的觸摸屏支持?

解決方案

要相對準確地檢測bom中用戶的觸摸屏支持,我們需要綜合運用幾種方法,因為沒有一個銀彈能解決所有情況,特別是面對混合設備時。

BOM中如何檢測用戶的觸摸屏支持?

首先,最直接且現代的屬性是 navigator.maxTouchPoints。這個屬性返回設備支持的最大并發觸摸點數。如果它大于0,通常意味著設備具備觸摸輸入能力。

if (navigator.maxTouchPoints > 0) {     console.log("設備可能支持觸摸屏,最大觸摸點數: " + navigator.maxTouchPoints);     // 進一步的邏輯,例如調整UI } else {     console.log("設備可能不支持觸摸屏,或當前沒有活動的觸摸輸入。"); }

然而,僅僅依賴 navigator.maxTouchPoints 并不總是完美的。比如,一些帶有手寫筆輸入的設備,maxTouchPoints 也會大于0,但用戶可能并不習慣用手指觸摸。更重要的是,我們常常想知道的不是“設備有沒有觸摸能力”,而是“用戶當前是否主要通過觸摸進行交互”。

BOM中如何檢測用戶的觸摸屏支持?

這時,window.matchMedia 配合css媒體查詢就顯得尤為重要,特別是 (hover: none) and (pointer: coarse) 這個組合。

  • hover: none:表示主輸入設備不支持懸停。鼠標和觸控板通常支持懸停,而手指觸摸則不支持。
  • pointer: coarse:表示主輸入設備的精確度較低,通常指手指觸摸。鼠標和手寫筆通常是 pointer: fine。

將兩者結合起來,可以更準確地判斷設備是否主要為觸摸設計,或用戶傾向于使用觸摸:

function isTouchDevice() {     // 檢查 maxTouchPoints     const hasTouchPoints = navigator.maxTouchPoints > 0;      // 檢查媒體查詢     const prefersTouchInteraction = window.matchMedia('(hover: none) and (pointer: coarse)').matches;      // 綜合判斷,但需要注意,這依然是一種推斷     return hasTouchPoints && prefersTouchInteraction; }  if (isTouchDevice()) {     console.log("根據綜合判斷,這很可能是一個主要通過觸摸交互的設備。");     // 針對觸摸屏優化UI } else {     console.log("這可能是一個鼠標/鍵盤主導的設備,或混合設備。"); }

這種組合判斷通常更為可靠,它試圖捕捉用戶交互的“意圖”而非僅僅是硬件能力。當然,它也并非萬無一失,例如一些桌面瀏覽器為了開發者調試,可能會模擬觸摸事件,從而導致誤判。

為什么僅僅檢查ontouchstart不足以判斷觸摸屏支持?

在過去,開發者確實很喜歡用 document.documentElement.ontouchstart !== undefined 這樣的方式來判斷觸摸屏支持。我個人也用過,覺得方便快捷。但說實話,這種方法現在看來,用“過時”來形容都顯得客氣了,它根本就是不準確的。

首先,ontouchstart 只是一個事件處理器屬性的存在與否,它反映的是瀏覽器是否支持 touchstart 這個事件,而不是設備是否真的有觸摸屏。很多桌面瀏覽器,為了兼容性和方便開發者調試,即使沒有觸摸屏,也可能在 window 或 document 對象上暴露 ontouchstart 屬性。這就像你家里裝了門鈴按鈕,但并不代表你家外面真的有人在按門鈴。

其次,即使 ontouchstart 存在,也無法告訴你設備的觸摸能力是怎樣的,比如是單點觸摸還是多點觸摸。它更無法區分是手指觸摸、手寫筆觸摸,還是某種輔助設備。現代前端開發需要更精細的控制和判斷,而 ontouchstart 提供的粒度太粗糙了。

再者,這種基于事件屬性的特性檢測,在標準化的道路上已經被 navigator.maxTouchPoints 和媒體查詢所取代。后者提供了更明確、更符合W3C規范的方式來獲取這些信息。依賴一個非標準或已廢棄的檢測方式,無疑是在給自己未來的維護挖坑。所以,當我看到代碼里還在用 ontouchstart 做判斷時,總會覺得有點惋惜,畢竟有更好的方式擺在那里。

混合設備(如觸屏筆記本)的觸摸檢測有哪些特殊考量?

混合設備,比如那些帶觸摸屏的筆記本電腦,或者某些二合一平板電腦,是觸摸檢測中最讓人頭疼的場景。它們同時擁有鼠標/觸控板和觸摸屏兩種輸入方式,這就讓我們的判斷變得復雜起來。

我的經驗是,在這種設備上,navigator.maxTouchPoints 幾乎總是大于0,因為它們確實有觸摸屏。但關鍵在于 window.matchMedia(‘(hover: none) and (pointer: coarse)’) 的表現。很多時候,如果筆記本的主輸入模式仍然被認為是鼠標/觸控板(例如,用戶更頻繁地使用觸控板),那么 hover: hover 和 pointer: fine 可能會是默認值。這意味著,即使設備有觸摸能力,瀏覽器也可能認為用戶當前更傾向于使用精確的指針設備。

這種情況下,我們面臨的挑戰是:是根據設備能力來調整UI,還是根據用戶當前的實際交互模式來調整?我個人傾向于后者。如果用戶正在用鼠標,即使設備支持觸摸,UI也應該優先考慮鼠標操作的便利性,例如顯示懸停效果。反之,如果用戶開始觸摸屏幕,那么UI應該立即響應,例如放大觸摸目標。

這就引出了一個更深層次的問題:我們真的需要“檢測”觸摸屏嗎?或者說,我們更應該“響應”觸摸事件?對于混合設備,我傾向于采取一種更動態、更“事件驅動”的策略。例如,當實際的 touchstart 事件發生時,我們才去切換UI到觸摸優化模式,而不是在頁面加載時就一刀切地判斷。這就像你不能因為一個人有汽車駕照,就假設他每次出門都開車,他可能今天想走路呢。

除了檢測,如何在Web應用中優化觸屏用戶體驗?

檢測觸摸屏支持只是第一步,真正的挑戰和價值在于如何基于這種檢測(或更直接地,基于觸摸事件本身)來優化Web應用的用戶體驗。這可不是簡單地把按鈕變大那么簡單,它涉及到很多細節,而且這些細節往往能決定用戶對你的應用是愛還是恨。

首先是觸摸目標(Touch Targets)。這是最基礎也最容易被忽視的一點。在觸摸屏上,用戶的指尖遠不如鼠標指針精確。所以,所有可點擊、可交互的元素,比如按鈕、鏈接、表單輸入框,都應該有足夠大的觸摸區域。通常建議至少44×44像素。我見過太多網站,在手機上點一個很小的圖標,點半天點不準,那種挫敗感真的讓人想摔手機。

其次是手勢支持。觸摸屏不僅僅是點擊,它還有滑動、捏合、雙指縮放等手勢。如果你的應用涉及到圖片瀏覽、地圖、長列表等,考慮加入這些手勢支持會極大提升用戶體驗。例如,圖片庫可以支持左右滑動切換,地圖可以支持雙指縮放。當然,這需要一些JavaScript庫或自定義實現來處理 touchstart, touchmove, touchend 事件。

再來是虛擬鍵盤的處理。當用戶在觸摸設備上點擊輸入框時,虛擬鍵盤會彈出來,這可能會遮擋一部分內容,甚至導致頁面布局錯亂。我們需要確保輸入框被聚焦時,它仍然在可視區域內,并且不會被鍵盤遮擋。有時候,可能需要用JavaScript來滾動視圖,或者調整布局。

還有一點很關鍵,是懸停(Hover)狀態的替代方案。在鼠標主導的設備上,我們習慣用 :hover 來給用戶提供視覺反饋,比如鼠標移到按鈕上時變色。但在觸摸屏上,沒有“懸停”這個概念。所以,那些只在懸停時才顯示的信息或功能,需要找到替代的展現方式,比如點擊后顯示,或者始終可見。

最后,性能。觸摸操作對頁面的響應速度非常敏感。任何卡頓、延遲都會讓用戶覺得應用“不跟手”。所以,優化動畫、減少不必要的重繪回流,確保JavaScript執行效率,對于觸摸屏用戶體驗來說至關重要。這就像你用手去觸碰一個物體,如果它反應遲鈍,你就會覺得它很“笨重”。

? 版權聲明
THE END
喜歡就支持一下吧
點贊11 分享