本文探讨了在 Web 开发中检测用户输入设备(触摸、鼠标、手写笔)的可靠方法,超越了屏幕尺寸检查或用户代理嗅探等不可靠的技术。 重点是利用 CSS 媒体查询,特别是 pointer
、hover
和 any-pointer
来进行准确的设备功能检测。 这些查询提供有关输入模式的精确信息,从而实现更易于访问和响应更快的 Web 应用程序。
虽然更简单的方法可能看起来很方便,但它们通常会产生不准确的结果。例如,用户将鼠标连接到智能手机会使基于尺寸的假设失效。 CSS 媒体查询提供了卓越的解决方案,根据实际设备特性提供精确的数据。
CSS 媒体查询:一种可靠的方法
本文深入研究了 pointer
和 hover
媒体查询,演示了它们作为 React hooks 的实现。
pointer
媒体查询
pointer
媒体查询确定定点设备的存在和精度。它返回三个值之一:
none
:没有可用的指点设备(例如语音控制设备)。coarse
:存在指点设备,但缺乏精确度(例如,手指放在触摸屏上)。fine
:可以使用高精度的指点设备(例如鼠标)。window.matchMedia
方法提供了在代码中方便地访问媒体查询结果。
useMatchMedia
钩子
为了避免代码冗余,创建了一个自定义的 useMatchMedia
挂钩来检索和跟踪媒体查询结果。 该挂钩利用 window.matchMedia
并添加事件侦听器来检测查询匹配状态的变化。 清理函数可确保在组件卸载或查询更改时删除侦听器。
<code class="language-typescript">export const useMatchMedia = (query: string) => { const [matches, setMatches] = useState(false); useEffect(() => { const media = window.matchMedia(query); if (media.matches !== matches) { setMatches(media.matches); } const listener = () => setMatches(media.matches); media.addEventListener('change', listener); return () => media.removeEventListener('change', listener); }, [matches, query]); return matches; };</code>
检测主要指针功能
usePrimaryPointerQuery
钩子确定主指针类型。它调用 useMatchMedia
并查询 none
、coarse
和 fine
指针类型,从 Pointers
枚举返回适当的值。
<code class="language-typescript">import { useMatchMedia } from './useMatchMedia.ts'; import { Pointers } from './types.ts'; export const usePrimaryPointerQuery = () => { const isNone = useMatchMedia('(pointer: none)'); const isCoarse = useMatchMedia('(pointer: coarse)'); const isFine = useMatchMedia('(pointer: fine)'); if (isNone) { return Pointers.none; } else if (isCoarse) { return Pointers.coarse; } else if (isFine) { return Pointers.fine; } };</code>
检测额外的指针功能
虽然只有一个主指针存在,但设备可以有辅助指针(例如蓝牙键盘、操纵杆)。 any-pointer
媒体查询检查任何可用指针的精度。 useAnyPointerQuery
挂钩接受指针类型,并将 useMatchMedia
与动态生成的查询字符串一起使用。
<code class="language-typescript">export const useMatchMedia = (query: string) => { const [matches, setMatches] = useState(false); useEffect(() => { const media = window.matchMedia(query); if (media.matches !== matches) { setMatches(media.matches); } const listener = () => setMatches(media.matches); media.addEventListener('change', listener); return () => media.removeEventListener('change', listener); }, [matches, query]); return matches; };</code>
工作演示
展示钩子的完整演示现已推出:
高级检测:hover
和 any-hover
hover
和 any-hover
媒体查询通过检查悬停功能进一步完善检测。 将这些与 pointer
查询相结合可以实现更精确的设备识别。
Pointer value | Hover value | Device |
---|---|---|
coarse | none | Modern touch screens |
fine | none | Stylus-based devices |
coarse | hover | Joystick or TV remote |
fine | hover | Mouse |
例如,检测手写笔作为主要输入:
<code class="language-typescript">import { useMatchMedia } from './useMatchMedia.ts'; import { Pointers } from './types.ts'; export const usePrimaryPointerQuery = () => { const isNone = useMatchMedia('(pointer: none)'); const isCoarse = useMatchMedia('(pointer: coarse)'); const isFine = useMatchMedia('(pointer: fine)'); if (isNone) { return Pointers.none; } else if (isCoarse) { return Pointers.coarse; } else if (isFine) { return Pointers.fine; } };</code>
这种方法可确保更强大、更准确地检测用户输入设备,从而带来更好的用户体验和可访问性。
以上是如何使用浏览器媒体查询检测触摸设备的详细内容。更多信息请关注PHP中文网其他相关文章!