滑鼠測試能測出什麼:瀏覽器滑鼠事件看得到與看不到的
滑鼠開始連點、側鍵好像沒反應的時候,很多人會先上網找一個「滑鼠測試」網站按按看。我最近做了一個:Device Tester 裝置測試 ↗,可以測五顆按鍵、雙擊間隔、滾輪與點擊速度(CPS)。
做之前我以為這是個簡單的小工具。做完才發現,整個設計的核心其實是一個問題:網頁到底知道什麼? 答案是只知道瀏覽器交出來的事件。滑鼠的硬體、韌體、驅動程式和作業系統設定,網頁一樣都碰不到。所以工具頁面上寫得很直白:它只觀察瀏覽器收到的事件,不能直接診斷硬體。這篇把開發過程中弄清楚的幾件事整理出來。
看得到的:按鍵、點擊與滾輪事件
網頁拿得到的滑鼠資訊,主要來自這幾種事件:
- pointerdown/pointerup:按下與放開。事件上有
pointerType(mouse、pen 或 touch)、button(這次是哪一顆鍵變了)與buttons(現在按住了哪些鍵)。 - click、dblclick、auxclick、contextmenu:瀏覽器依按下與放開合成出來的高階事件。
- wheel:滾輪。帶有
deltaX、deltaY與單位deltaMode。
第一個容易搞混的地方是 button 和 buttons 的編號不一樣:
| 按鍵 | button 的值 | buttons 的位元 |
|---|---|---|
| 左鍵 | 0 | 1 |
| 中鍵(滾輪鍵) | 1 | 4 |
| 右鍵 | 2 | 2 |
| 上一頁鍵 | 3 | 8 |
| 下一頁鍵 | 4 | 16 |
中鍵與右鍵在兩個欄位裡是對調的。button 是「這一次變動的是哪顆鍵」,buttons 是「此刻所有按住的鍵」加總起來的位元遮罩。工具只把這五顆對應成名字,其他代碼一律列在「其他按鍵代碼」底下照實顯示,不猜它是什麼。
坑一:兩鍵同按時,第二顆鍵沒有 pointerdown
這是自動化驗收時在 Chrome 上抓到的。先按住左鍵、再加按右鍵、先放開左鍵、最後放開右鍵,實際收到的事件序列是:
pointerdown button=0 buttons=1 ← 按下左鍵
pointermove button=2 buttons=3 ← 加按右鍵(不是 pointerdown)
pointermove button=0 buttons=2 ← 放開左鍵(不是 pointerup)
pointerup button=2 buttons=0 ← 放開右鍵Pointer Events 規格就是這樣定義多鍵同按的:只有從「沒有任何鍵按著」變成「有鍵按著」才送 pointerdown,全部放開才送 pointerup,中間的變化都藏在 pointermove 裡。第一版只處理 pointerdown 和 pointerup,所以兩鍵同按時畫面上只亮左鍵。
修法是在每一次 pointermove 都拿 buttons 位元遮罩重新對一次「目前按住哪些鍵」。pointermove 一秒可能有上百個,所以遮罩沒變時直接回傳同一個狀態物件,Vue 就不會重新渲染;移動也不寫進事件紀錄、不送任何分析事件,它不是一個獨立的事件,只是用來修正按鍵狀態。
另一個細節是在測試區外放開按鍵。按下時對測試區呼叫 setPointerCapture,之後的事件都會送回測試區;全部按鍵都放開才釋放。再加上掛在 window 上的 pointerup 與 pointercancel 當保險,pointercancel 不會告訴你是哪顆鍵(button 是 −1),瀏覽器之後也不會再送這個指標的事件,所以收到就把所有按住的鍵一起清掉,避免畫面上永遠顯示某顆鍵「按住中」。
坑二:click 不一定是滑鼠點的
手機上點一下螢幕會觸發 click,用鍵盤聚焦按鈕再按 Enter 也會觸發 click。如果全部算進去,觸控就會被當成滑鼠左鍵。判斷規則是:
detail是 0 的 click 一律不算,這代表它是鍵盤觸發的。- 現行瀏覽器送出的 click 是 PointerEvent,有
pointerType就只認 mouse。 - 有些瀏覽器仍然送出沒有
pointerType的一般 MouseEvent,這時改看同一個測試區上一次 pointerdown 的來源。
代價是完全不支援 Pointer Events 的瀏覽器在雙擊測試區不會有數字。我寧可它失敗成「沒有資料」,也不要失敗成「把觸控當成滑鼠」,這跟頁面上「只記錄實體滑鼠輸入」的說明一致。點擊速度(CPS)測試更嚴格,只算 pointerType 是 mouse、而且是左鍵的 pointerdown。
看不到的:這幾件事網頁測不出來
作業系統的雙擊速度
網頁讀不到作業系統的雙擊速度設定,也就沒辦法用同一把尺判斷「這算不算雙擊」。所以雙擊區把兩件事分開顯示:
- 自己算的間隔:同一顆鍵相鄰兩次 click 的時間差,最新的排最前面。
- 瀏覽器的 dblclick 次數:只有瀏覽器依作業系統的設定,自己把兩次點擊合併成雙擊時才會增加。
如果你只按了一下,卻出現一個間隔很短的新紀錄,或 dblclick 次數增加了,代表這一下讓瀏覽器收到了兩次點擊。這很像微動開關彈跳造成的連點,但網頁不能直接確認:瀏覽器、擴充套件和系統的輸入設定都可能影響結果。所以工具只呈現事件,不替硬體下結論,並建議你換瀏覽器、檢查系統的雙擊速度、停用滑鼠相關的擴充套件,或把滑鼠接到另一台電腦比較。
上一頁、下一頁側鍵
瀏覽器與作業系統常把側鍵保留給頁面導覽,滑鼠的驅動軟體也可能改掉按鍵設定,所以按下的動作不一定傳得到網頁。側鍵顯示「未偵測」的意思是「這個頁面還沒收到它的事件」,不是「它壞了」。
DPI、回報率與硬體延遲
滾輪的 deltaY 很容易被誤會成「滾了幾格」。實際上它的單位看 deltaMode(0 是像素、1 是行、2 是頁),數值則是瀏覽器與系統處理過的結果,不同的輸入裝置與平台給的差很多。工具照原樣顯示 delta 與單位,只用變化比較大的那個方向判斷上下左右;滾輪測試區也不攔截捲動,頁面照樣可以捲,不會把人困在測試區裡。
同樣的道理,DPI、回報率(polling rate)和硬體延遲都測不到。例如多數瀏覽器會把高頻的移動事件合併、配合畫面更新的節奏才交給網頁,網頁上數到的 pointermove 次數不等於滑鼠實際的回報次數。與其給一個看起來很專業、其實不準的數字,工具乾脆不顯示這些項目,並在說明裡寫清楚原因。
點擊速度怎麼算才不灌水
CPS 測試從第一下點擊開始計時,可以選 1、5、10、30 秒,或自訂 1 到 60 秒的整數。剛開始的一瞬間,經過的時間很短,這時算出來的即時速度會暴衝,所以前 250 毫秒不顯示即時數字。時間到了之後,成績一律用「總點擊數除以完整秒數」計算。
最佳成績依秒數分開記在瀏覽器的 localStorage,只存每個秒數的最高分,可以一鍵清除。
隱私:事件不離開你的瀏覽器
滑鼠測試看起來無害,但事件資料其實很細:每一次按鍵的時間、間隔、滾輪數值。所以規則訂得很死:
- 只用標準的 Pointer、Mouse 與 Wheel 事件,不要求相機、麥克風或任何裝置權限。
- 按鍵代碼、座標、事件時間、點擊間隔、滾輪 delta 和成績,都不會送到分析服務。
- 分析只收固定的摘要事件:語言、開始某個測試、完成、重設、清除本機紀錄。自動的 page_view、Google Signals 與廣告個人化都關閉。
小結
- 網頁只看得到事件:硬體、驅動與作業系統設定都在牆的另一邊。
- 多鍵同按藏在 pointermove 裡:要用
buttons位元遮罩對帳,不能只聽按下與放開。 - 先排除不是滑鼠的輸入:鍵盤觸發的 click 與觸控都不算。
- 測不到的就不假裝測得到:雙擊速度、DPI、回報率,老實寫出來比給一個數字有用。
工具在這裡:Device Tester 裝置測試 ↗,打開瀏覽器就能測,不用安裝。各項測試的用法可以看Device Tester 工具介紹。
