简体   繁体   English

检测浏览器功能和鼠标和触摸的选择性事件

[英]Detecting browser capabilities and selective events for mouse and touch

I started using touch events for a while now, but I just stumbled upon quite a problem. 我现在开始使用触摸事件一段时间了,但我偶然发现了一个很大的问题。 Until now, I checked if touch capabilities are supported, and applied selective events based on that. 到目前为止,我检查了是否支持触摸功能,并根据它来应用选择性事件。 Like this: 像这样:

if(document.ontouchmove === undefined){
    //apply mouse events
}else{
    //apply touch events
}

However, my scripts stopped working in Chrome5 (which is currently beta) on my computer. 但是,我的脚本在我的计算机上停止使用Chrome5(目前是测试版)。 I researched it a bit, and as I expected, in Chrome5 (as opposed to older Chrome, Firefox, IE, etc.) document.ontouchmove is no longer undefined but null . 我研究了一下,正如我所预料的那样,在Chrome5中(相对于较旧的Chrome,Firefox,IE等), document.ontouchmove不再是undefined而是null

At first I wanted to submit a bug report, but then I realized: There are devices that have both mouse and touch capabilities, so that might be natural, maybe Chrome now defines it because my OS might support both types of events. 起初我想提交一个错误报告,但后来我意识到:有些设备同时具有鼠标和触摸功能,所以这可能很自然,也许Chrome现在定义它,因为我的操作系统可能支持这两种类型的事件。

So the solutions seems easy: Apply BOTH event types. 所以解决方案看起来很简单:应用BOTH事件类型。 Right? 对?

Well the problem now take place on mobile. 那么问题现在发生在移动设备上。 In order to be backward compatible and support scripts that only use mouse events, mobile browsers might try to fire them as well (on touch). 为了向后兼容并支持仅使用鼠标事件的脚本,移动浏览器也可能尝试触发它们(触摸时)。 So then with both mouse and touch events set, a certain handler might be called twice every time. 因此,设置鼠标和触摸事件后,每次都可以调用某个处理程序两次。

What is the way to approach this? 有什么方法可以解决这个问题? Is there a better way to check and apply selective events, or must I ignore the problems that might occur if browsers fire both touch and mouse events at times? 是否有更好的方法来检查和应用选择性事件,或者我是否必须忽略浏览器有时同时触发触摸和鼠标事件时可能出现的问题?

Try creating a dummy element and attaching a touch event handler to it, then check if the handler is of type "function". 尝试创建一个虚拟元素并将触摸事件处理程序附加到它,然后检查处理程序是否为“function”类型。 This is not foolproof though as some browsers will allow touch event handlers although they are running on a non-touch device - but it's probably as close as you'll get. 这并不是万无一失的,因为有些浏览器会允许触摸事件处理程序,尽管它们运行在非触摸设备上 - 但它可能会尽可能接近你。 So, something like this: 所以,像这样:

var hasTouch = function() {
    var dummy = document.createElement("div");
    dummy.setAttribute("ontouchmove", "return;");
    return typeof dummy.ontouchmove == "function" ? true : false;
}

Happy coding! 快乐的编码!

Try disabling the mouse events if the touch events fire? 如果触摸事件触发,请尝试禁用鼠标事件?

Eg: 例如:

 function touch_events() { document.onmousemove = null; ... } function mouse_events() { ... } document.ontouchmove = touch_events; document.onmousemove = mouse_events; 

Is this too obvious? 这太明显了吗?

if(document.ontouchmove !== undefined || document.ontouchmove == null){
    //apply touch events
}else{
    //apply mouse events
}

var support_touch =(typeof Touch ==“object”);

Did I get this wrong, or did every post so far here answer a question that you didn't ask? 难道犯了这个错误,还是每一个岗位,到目前为止在这里回答你没有问一个问题吗? At least you now have loads of alternative ways to check for supported events :) 至少你现在有很多替代方法来检查支持的事件:)

Anyway, regarding your question: I would say it depends on what you are building. 无论如何,关于你的问题:我会说这取决于你正在建设什么。 I assume when you write "applied selective events based on that" you mean adding event Listeners and -Handlers? 我假设当您编写“基于此的应用选择性事件”时,您的意思是添加事件监听器和-Handlers? Also i assume you're not dealing with multitouch (yet)? 另外我假设你还没有处理多点触控(还)?

In general, if you want your app to work with both input event types, you're left without a choice but to register listeners for all of those. 通常,如果您希望您的应用程序使用两种输入事件类型,那么您将无法选择,只能为所有这些选择注册侦听器。 You might be using the same handler for touchstart and mousedown already, so that's the place i would make sure only one out of subsequent identical events is actually processed (to save cpu cycles and redraws as well as help avoiding possible side effects). 你可能已经使用了touchstartmousedown的相同处理程序,所以这就是我确保实际处理后续相同事件中只有一个(保存cpu周期和重绘以及帮助避免可能的副作用)的地方。

When it comes to touch devices, speaking of single touch, i can see my level 10 (2.3.3) phone generates both event - the mouse events, so "classic" web (all those onmousedown -events, etc...) will work, the touch events... well, because it's a touch device apparently. 谈到触摸设备,说到单触,我可以看到我的10级(2.3.3)电话产生两个事件 - 鼠标事件,所以“经典”网络(所有那些onmousedown -events等...)工作,触摸事件......好吧,因为它显然是一个触摸设备。 But only checking if the javascript API supports TouchEvents doesn't tell you anything about the input device, for instance: the rekonq browser on kubuntu desktop returns true for the above examples - but it will never fire them unless used with a touchscreen. 但只检查javascript API是否支持TouchEvents,并不会告诉您有关输入设备的任何信息,例如:kubuntu桌面上的rekonq浏览器对于上述示例返回true - 但除非与触摸屏一起使用,否则它将永远不会触发它们。

Maybe telling devices apart via window.navigator.userAgent would be a more feasible approach? 也许通过window.navigator.userAgent告诉设备是一种更可行的方法?

Similar to Ola's answer, I've found just a simple detect works but I also find that in particular quirky android devices (like the wildfire) don't always have this event defined - this works well for me: 类似于Ola的答案,我发现只是一个简单的检测工作,但我也发现特别古怪的Android设备(如野火)并不总是定义这个事件 - 这对我很有用:

//detect capabilities
this.is_touch_device = ('ontouchstart' in document.documentElement) || (navigator.userAgent.match(/ipad|iphone|android/i) != null);

//if so do somemthing
if (this.is_touch_device) {
    //like publishing a custom event 
}

(probably a better way of doing this :) (可能是一个更好的方法:)

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

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