简体   繁体   English

响应桌面和移动设备中的touchstart和mousedown,而无需嗅探

[英]Responding to touchstart and mousedown in desktop and mobile, without sniffing

So, I have a problem. 所以,我有一个问题。 I want to respond to a user pressing the mouse button (on desktop) or touching a div (on mobile). 我想对用户按下鼠标按钮(在桌面上)或触摸div(在移动设备上)做出回应。 I'm trying to be compatile with evergreen browsers. 我正在尝试与常绿的浏览器兼容。 This is what I tried so far: 这是我到目前为止尝试过的:

  • listen only to mouseDown event. 仅侦听mouseDown事件。 This works on desktop but doesn't work in mobile if the user is dragging. 这适用于桌面设备,但如果用户拖动则不适用于移动设备。 I want the handler to be called as soon as the user touches the screen, no matter if they're moving their finger in the process. 我希望在用户触摸屏幕时立即调用处理程序,无论他们在过程中是否在移动手指。
  • listen only to touchStart event. touchStart事件。 This works on mobile and desktop, except for Edge and Safari desktop, which don't support touch events. 此功能适用于移动设备和台式机,但Edge和Safari台式机除外,它们不支持触摸事件。
  • listen to both, then preventDefault . 都听,然后preventDefault This causes a double handler call on Chrome mobile. 这会在Chrome移动版上引起双重处理程序调用。 It seems that touch events are passive to allow uninterrupted scrolling on mobile Chrome, so preventDefualt has no effect on them . 触摸事件似乎是被动的,它允许在移动Chrome上进行不间断的滚动,因此preventDefualt没有任何影响。 What I get is a warning message saying "[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080" in the console, preventDefault is ignored and my event is called twice. 我得到的是一条警告消息,内容为: "[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080" ,在控制台中将preventDefault忽略并我的活动叫了两次。

Obviously this can be solved by sniffing touch events, but the net is full of self-righteous rants on how one has to be device-agnostic and that it's dangerous to detect touch events before the user interacted . 显然,这可以通过嗅探触摸事件来解决,但是网络上充满了自以为是的声音,说明人们必须如何与设备无关,并且在用户交互之前检测触摸事件很危险

So I guess that the question is: is there a way to do what I want to do without sniffing for touch events? 因此,我想问题是:是否可以在不嗅探触摸事件的情况下做我想做的事情?

Below my sample React code: 在我的示例React代码下面:

function handler(e) {
    console.log('handler called')
    e.preventDefault()
}

export default function MyElement() {
    return (
        <div
            onMouseDown={handler}
            onTouchStart={handler}
        >
        Hello
        </div>
    )
}

It turn out it's not yet possible in React . 事实证明,在React中还不可能 One workaround is set a flag the first time touchStart it's received. 一种解决方法是在第一次收到touchStart其设置为标志。

touchHandler = () => {
  this.useTouch = true
  this.realHandler()
}

mouseHandler = () => {
  if (this.useTouch) return
  this.realHandler()
}

With the caveat that the first touchStart can be lost in case of dragging. 请注意,在touchStart可能会丢失第一个touchStart

Quite disappointing. 非常令人失望。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM