我知道您可以按照以下答案检测浏览器是否在带有触摸屏的设备上运行:https://stackoverflow.com/a/4819886/589921
但是,我知道有些设备同时具有触摸屏和鼠标。我可以检测到这些类型的触摸之间的差异吗?本质上我想区分 3 个不同的事件:
onClick
(在单击或触摸时触发)、onTouch
(仅在触摸时触发)、onMouseClick
(仅在单击时触发)。
您可以使用 pointerType
PointerEvent
属性来检测输入类型("mouse"
、"touch"
或 "pen"
):
element.addEventListener('pointerup', (event) => {
if (event.pointerType === "mouse") {}
if (event.pointerType === "touch") {}
if (event.pointerType === "pen") {}
});
注意 - 我已使用
pointerup
事件来匹配 click
的行为,但您也可以使用 pointerdown
。
如果您想要每种类型的点击都有特定事件,您可以创建自定义事件:
const mouse = new Event("mouseclick");
const touch = new Event("touch");
document.addEventListener("pointerup", ({ pointerType, target }) => {
if (pointerType === "mouse") target.dispatchEvent(mouse);
if (pointerType === "touch") target.dispatchEvent(touch);
});
const someElement = document.querySelector(".box");
someElement.addEventListener("mouseclick", () => {
console.log("Clicked with mouse");
});
someElement.addEventListener("touch", () => {
console.log("Touched with mobile device");
});
someElement.addEventListener("click", () => {
console.log("Clicked by any device");
});
.box {
position: absolute;
inset: 2em;
background: darkred;
padding: 1em;
}
<div class="box">A box with custom events</div>
在 iOS 17 上针对移动设备进行了测试,但这应该适用于任何浏览器。
请注意,如果您使用 React 或其他框架,可能有不同的方法来创建自定义事件。
例如,在 React 中,您可以使用可重用函数来实现这些事件:
function pointerEvents(
listeners: {
onMouse?: (event: PointerEvent) => void;
onTouch?: (event: PointerEvent) => void;
}
) {
return {
onPointerUp(event) {
const { pointerType } = event;
if (pointerType === "mouse") {
listeners.onMouseClick?.(event);
} else if (pointerType === "touch") {
listeners.onTouch?.(event);
}
},
};
}
function MyComponent() {
return (
<button
className="something"
{...pointerEvents({
onMouse: (e) => { /* … */ },
onTouch: (e) => { /* … */ },
})}
>
Click me
</button>
);
}