nra*_*aud 140 javascript mouse html5 touch
我正在开发一个webapp(不是一个有趣文本页面的网站),它有一个非常不同的触摸界面(当你点击时你的手指隐藏屏幕)和鼠标(严重依赖于悬停预览).如何检测到我的用户没有鼠标向他显示正确的界面?我计划为鼠标和触摸的人留下一个开关(就像一些笔记本电脑).
浏览器中的触摸事件功能实际上并不意味着用户正在使用触摸设备(例如,Modernizr不会剪切它).如果设备有鼠标,正确回答问题的代码应该返回false,否则返回true.对于具有鼠标和触摸功能的设备,它应该返回false(不是仅触摸)
作为旁注,我的触摸界面可能也适用于仅限键盘的设备,因此更多的是缺少我想要检测的鼠标.
为了使需求更加清晰,以下是我要实现的API:
// Level 1
// The current answers provide a way to do that.
hasTouch();
// Returns true if a mouse is expected.
// Note: as explained by the OP, this is not !hasTouch()
// I don't think we have this in the answers already, that why I offer a bounty
hasMouse();
// Level 2 (I don't think it's possible, but maybe I'm wrong, so why not asking)
// callback is called when the result of "hasTouch()" changes.
listenHasTouchChanges(callback);
// callback is called when the result of "hasMouse()" changes.
listenHasMouseChanges(callback);
Run Code Online (Sandbox Code Playgroud)
Wya*_*att 59
主要问题是您有以下不同类别的设备/用例:
更糟糕的是,人们可以从其中一些类转换到其他类(插入鼠标,连接到键盘),或者用户可以在正常的笔记本电脑上显示,直到它们伸出并触摸屏幕.
假设浏览器中存在事件构造函数不是向前推进的好方法(并且它有些不一致),这是正确的.此外,除非您正在跟踪特定事件或仅尝试排除上述几个类,否则使用事件本身并不是完全证明.
例如,假设您发现用户已发出真正的鼠标移动(而不是触摸事件中的错误移动,请参阅http://www.html5rocks.com/en/mobile/touchandmouse/).
那又怎样?
你启用悬停样式?你添加更多按钮?
无论哪种方式,你都要增加玻璃时间,因为你必须等待事件发生.
但是当你的高贵用户决定拔掉他的鼠标并完全触摸时会发生什么...你是否等待他触摸你现在挤满的界面,然后在他努力确定你现在拥挤的用户界面之后立即改变它?
在子弹形式,引用stucox在https://github.com/Modernizr/Modernizr/issues/869#issuecomment-15264101
- 我们想要检测鼠标的存在
- 在事件发生之前,Ae可能无法检测到
- 因此,我们正在检测的是,如果在此会话中使用了鼠标 - 它将不会立即从页面加载
- 我们可能也无法检测到没有鼠标 - 它是真的未定义(我认为这比设置它更有意义,直到证明)
- 而且我们可能无法检测鼠标是否在会话期间断开连接 - 这与用户放弃鼠标无法区分
抛开:浏览器知道用户何时插入鼠标/连接键盘,但不会将其暴露给JavaScript ..当然!
这应该会引导您进行以下操作:
跟踪给定用户的当前能力是复杂的,不可靠的,并且具有可疑的优点
但是,渐进式增强的想法在这里很适用.无论用户的上下文如何,都可以构建一种平稳运行的体验.然后根据浏览器功能/媒体查询进行假设,以添加在假定上下文中相对的功能.鼠标的存在只是不同设备上不同用户体验您网站的众多方式之一.在内核中创建具有优点的东西,不要过于担心人们如何点击按钮.
Dan*_*Dan 55
如何在文档上监听mousemove事件.然后,直到您听到该事件,您才认为该设备仅为触摸或键盘.
var mouseDetected = false;
function onMouseMove(e) {
unlisten('mousemove', onMouseMove, false);
mouseDetected = true;
// initializeMouseBehavior();
}
listen('mousemove', onMouseMove, false);
Run Code Online (Sandbox Code Playgroud)
(在何处listen,unlisten代表addEventListener或attachEvent酌情委托.)
希望这不会导致太多的视觉冲击,如果您需要基于模式的大量重新布局,它会很糟糕...
Hug*_*lva 23
@ Wyatt的答案很棒,给了我们很多思考.
在我的情况下,我选择听第一次互动,然后才设置一个行为.因此,即使用户有鼠标,如果第一次互动是触摸,我将视为触摸设备.
我们可以假设如果在触摸之前触发鼠标事件,则它是真正的鼠标事件,而不是模拟事件.示例(使用jQuery):
$(document).ready(function() {
var $body = $('body');
var detectMouse = function(e){
if (e.type === 'mousedown') {
alert('Mouse interaction!');
}
else if (e.type === 'touchstart') {
alert('Touch interaction!');
}
// remove event bindings, so it only runs once
$body.off('mousedown touchstart', detectMouse);
}
// attach both events to body
$body.on('mousedown touchstart', detectMouse);
});
Run Code Online (Sandbox Code Playgroud)
这对我有用
Bla*_*bam 21
截至2018年,有一种良好可靠的方法可以检测浏览器是否有鼠标(或类似的输入设备):CSS4媒体交互功能已被大多数现代浏览器支持(其余部分即将推出).
W3C:
指针媒体特征用于查询诸如鼠标的指示设备的存在和准确性.
请参阅以下选项:
/* The primary input mechanism of the device includes a
pointing device of limited accuracy. */
@media (pointer: coarse) { ... }
/* The primary input mechanism of the device
includes an accurate pointing device. */
@media (pointer: fine) { ... }
/* The primary input mechanism of the
device does not include a pointing device. */
@media (pointer: none) { ... }
/* Primary input mechanism system can
hover over elements with ease */
@media (hover: hover) { ... }
/* Primary input mechanism cannot hover
at all or cannot conveniently hover
(e.g., many mobile devices emulate hovering
when the user performs an inconvenient long tap),
or there is no primary pointing input mechanism */
@media (hover: none) { ... }
/* One or more available input mechanism(s)
can hover over elements with ease */
@media (any-hover: hover) { ... }
/* One or more available input mechanism(s) cannot
hover (or there are no pointing input mechanisms) */
@media (any-hover: none) { ... }
Run Code Online (Sandbox Code Playgroud)
媒体查询也可以在JS中使用:
if(window.matchMedia("(any-hover: none)").matches) {
// do sth
}
Run Code Online (Sandbox Code Playgroud)
有关:
https://drafts.csswg.org/mediaqueries/#mf-interaction
小智 9
只能检测浏览器是否具有触控功能.没有办法知道它是否实际上有触摸屏或鼠标连接.
如果检测到触摸能力,则可以通过监听触摸事件而不是鼠标事件来优先使用.
要检测跨浏览器的触摸功能:
function hasTouch() {
return (('ontouchstart' in window) || // html5 browsers
(navigator.maxTouchPoints > 0) || // future IE
(navigator.msMaxTouchPoints > 0)); // current IE10
}
Run Code Online (Sandbox Code Playgroud)
然后可以用它来检查:
if (!hasTouch()) alert('Sorry, need touch!);
Run Code Online (Sandbox Code Playgroud)
或选择要收听的事件:
var eventName = hasTouch() ? 'touchend' : 'click';
someElement.addEventListener(eventName , handlerFunction, false);
Run Code Online (Sandbox Code Playgroud)
或使用单独的触摸与非触摸方法:
if (hasTouch() === true) {
someElement.addEventListener('touchend' , touchHandler, false);
} else {
someElement.addEventListener('click' , mouseHandler, false);
}
function touchHandler(e) {
/// stop event somehow
e.stopPropagation();
e.preventDefault();
window.event.cancelBubble = true;
// ...
return false; // :-)
}
function mouseHandler(e) {
// sorry, touch only - or - do something useful and non-restrictive for user
}
Run Code Online (Sandbox Code Playgroud)
对于鼠标,只能检测鼠标是否被使用,而不是它是否存在.可以设置一个全局标志来指示鼠标是否被使用检测到(类似于现有的答案,但简化了一点):
var hasMouse = false;
window.onmousemove = function() {
hasMouse = true;
}
Run Code Online (Sandbox Code Playgroud)
(一个不能包含mouseup或mousedown因为这些事件也可以通过触摸触发)
浏览器限制对低级系统API的访问,这些API需要能够检测诸如正在使用的系统的硬件功能之类的功能.
有可能编写插件/扩展来访问这些,但是通过JavaScript和DOM,这样的检测仅限于此目的,并且必须编写专用于各种OS平台的插件.
总而言之:这种检测只能通过"好猜测"来估算.
当Media Queries Level 4在浏览器中可用时,我们将能够使用"指针"和"悬停"查询来使用鼠标检测设备.
如果我们真的想要将这些信息传达给Javascript,我们可以使用CSS查询根据设备类型设置特定样式,然后使用getComputedStyleJavascript来读取该样式,并从中派生原始设备类型.
但是可以随时连接或拔出鼠标,用户可能想要在触摸和鼠标之间切换.因此,我们可能需要检测此更改,并提供更改界面或自动执行此操作.
既然您计划提供一种在接口之间切换的方法,那么只需要用户点击链接或按钮"输入"正确版本的应用程序是否可行?然后你可以记住他们对未来访问的偏好.它不是高科技,但它100%可靠:-)
小智 6
这在类似的情况下对我有用。基本上,假设用户没有鼠标,直到您看到一系列短的连续鼠标移动,而无需干预鼠标按下或鼠标松开。不是很优雅,但是很有效。
var mousedown = false;
var mousemovecount = 0;
function onMouseDown(e){
mousemovecount = 0;
mousedown = true;
}
function onMouseUp(e){
mousedown = false;
mousemovecount = 0;
}
function onMouseMove(e) {
if(!mousedown) {
mousemovecount++;
if(mousemovecount > 5){
window.removeEventListener('mousemove', onMouseMove, false);
console.log("mouse moved");
$('body').addClass('has-mouse');
}
} else {
mousemovecount = 0;
}
}
window.addEventListener('mousemove', onMouseMove, false);
window.addEventListener('mousedown', onMouseDown, false);
window.addEventListener('mouseup', onMouseUp, false);
Run Code Online (Sandbox Code Playgroud)
Mar*_*ope -7
通常,检测是否支持鼠标悬停功能比检测操作系统/浏览器类型更好。您可以简单地通过以下操作来做到这一点:
if (element.mouseover) {
//Supports the mouseover event
}
Run Code Online (Sandbox Code Playgroud)
确保您不执行以下操作:
if (element.mouseover()) {
// Supports the mouseover event
}
Run Code Online (Sandbox Code Playgroud)
后者实际上会调用该方法,而不是检查它是否存在。
您可以在这里阅读更多信息: http: //www.quirksmode.org/js/support.html
| 归档时间: |
|
| 查看次数: |
42157 次 |
| 最近记录: |