可以吗?
#1 楼
更新:在将整个功能检测库引入项目之前,请阅读下面的blmstr答案。检测实际的触摸支持更为复杂,而Modernizr仅涵盖一个基本用例。Modernizr是一种出色的轻量级方法,可在任何站点上执行各种功能检测。
它只是将每个功能的类添加到html元素中。
然后您可以在CSS和JS中轻松定位这些功能。例如:
html.touch div {
width: 480px;
}
html.no-touch div {
width: auto;
}
和Javascript(jQuery示例):
$('html.touch #popup').hide();
评论
Modernizr不会测试触摸屏。它测试浏览器中是否存在触摸事件。请参阅文档中的“其他测试”部分:modernizr.com/docs/#features-misc
–哈里·洛夫(Harry Love)
2012年1月24日17:15
如果(Modernizr.touch){/ *做触摸东西/}其他{/很好,不要* /},您还可以对触摸事件是否存在进行JS测试
–分析家G
2012-02-10 18:27
以@harrylove的观点来说,自Windows 8发布以来,Modernizr一直错误地将我所有PC浏览器返回为兼容触摸屏。
–安东
13年2月18日在15:12
更新:blmstr的答案更好,并且是纯Javascript解决方案。
–艾伦·克里斯托弗·托马斯(Alan Christopher Thomas)
2013年6月17日19:22
如果Modernizr.touch意外返回undefined,则您可能具有自定义的Modernizr(可以选择),而不支持触摸事件检测。
– Henrik N
15年2月24日在7:45
#2 楼
您是否尝试过使用此功能? (这与以前使用的Modernizr相同。) function is_touch_device() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
console.log(is_touch_device());
UPDATE 1
document.createEvent("TouchEvent")
已开始以最新的Chrome(v。17)返回true
。 Modernizr前不久对此进行了更新。在此处检查Modernizr测试。像这样更新您的功能以使其起作用:
function is_touch_device1() {
return 'ontouchstart' in window;
}
console.log(is_touch_device1());
更新2
我发现以上内容不适用于IE10(在MS Surface上返回false)。解决方法如下:
function is_touch_device2() {
return 'ontouchstart' in window // works on most browsers
|| 'onmsgesturechange' in window; // works on IE10 with some false positives
};
console.log(is_touch_device2());
UPDATE 3
'onmsgesturechange' in window
在某些IE桌面版本中将返回true,因此并不可靠。这样可以更可靠地工作: function is_touch_device3() {
return !!('ontouchstart' in window // works on most browsers
|| navigator.maxTouchPoints); // works on IE10/11 and Surface
};
console.log(is_touch_device3());
Update 2018
随着时间的流逝,有更多更好的新方法可以对此进行测试。我基本上已经提取并简化了Modernizr的检查方式:
function is_touch_device4() {
if ("ontouchstart" in window || window.TouchEvent)
return true;
if (window.DocumentTouch && document instanceof DocumentTouch)
return true;
const prefixes = ["", "-webkit-", "-moz-", "-o-", "-ms-"];
const queries = prefixes.map(prefix => `(${prefix}touch-enabled)`);
return window.matchMedia(queries.join(",")).matches;
}
console.log(is_touch_device4());
在这里,他们使用的是非标准的
touch-enabled
媒体查询功能,我认为这是一种奇怪且不明智的做法。但是,在现实世界中,我猜它是可行的。将来(当所有人都支持它们时),这些媒体查询功能可以为您提供相同的结果:pointer
和hover
。说明了触摸检测的问题,请参阅:Stu Cox:您无法检测到触摸屏。
评论
双爆炸将一个值强制转换为布尔值,强制该函数返回true或false。您可以在这里阅读有关它的更多信息:stackoverflow.com/questions/4686583/…
–Rob Flaherty
2012年4月28日14:00
这不适用于Opera Mobile 10或Internet Explorer Mobile 6(Windows Mobile 6.5)。
– doubleJ
2012年6月20日的19:00
双int(!!)是多余的,因为in运算符已经计算为布尔值。
–史蒂夫
2012年11月6日19:04
即使在非触摸设备(PC)中,“ onmsgesturechange”也评估为是。 window.navigator.msMaxTouchPoints似乎更准确。在这里找到它。
–史蒂夫
2012年11月20日在21:02
即使我的屏幕没有触摸传感器,在Windows 8的IE10上它的评估结果也正确。我将旧笔记本电脑从Windows 7升级到Windows 8。
– Pwner
2012年11月26日23:30
#3 楼
由于Modernizr在Windows Phone 8 / WinRT上未检测到IE10,因此一个简单的跨浏览器解决方案是:var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
您只需要检查一次设备即可不会突然支持或不支持触摸,因此只需将其存储在变量中即可更有效地使用它多次。
评论
窗口中的“ onmsgesturechange”还可以检测非触摸设备上的“桌面” IE10,因此这不是确定触摸的可靠方法。
–马特·斯托
13年1月20日在1:28
这个答案应该是可以接受的,因为它是最好,最简单且最新的答案。在一个函数中,我认为这会更加一致:return !!(窗口中的“ ontouchstart”)|| !!(window.navigator中的'msmaxtouchpoints'); (结合两个答案)在IE10中也能正常工作!
–叶提
13年4月9日在14:15
这应该是公认的答案。即使可以触摸,窗口中的“ onmsgesturechange”也将在IE10桌面上返回true
–山姆·桑顿
13年5月3日在16:51
您所需要的全部:函数isTouchDevice(){在窗口||中返回'ontouchstart' !!(navigator.msMaxTouchPoints);}
–GFoley83
2013年9月4日在6:20
甚至GFoley在窗口中建议“ ontouchstart” || !!(navigator.msMaxTouchPoints);在2014年2月Chrome 30开发者中返回的错误分数为正。
–汤姆·安德森(Tom Andersen)
2014年2月7日在17:39
#4 楼
由于引入了交互媒体功能,因此您可以轻松做到:if(window.matchMedia("(pointer: coarse)").matches) {
// touchscreen
}
https://www.w3.org/TR/mediaqueries-4/#descdef-media- any-pointer
更新(由于评论):上述解决方案是检测“粗指针”(通常是触摸屏)是否是主要输入设备。万一您想确定某个设备是否具有例如鼠标也有触摸屏,您可以改用
any-pointer: coarse
。有关更多信息,请参见此处:检测浏览器没有鼠标并且仅触摸
评论
这是迄今为止最好的解决方案,谢谢!尽管我建议使用(指针:粗糙的),因为您很可能只针对主要输入。由于少数不支持的浏览器仅是台式机,因此可以在生产中使用。在css-tricks上有一篇很棒的文章。
–法比安·冯·埃勒兹(Fabian von Ellerts)
19-4-9在9:17
这是我测试过的唯一可在每种情况下使用的解决方案。谢谢!
–kaiserkiwi
2月20日14:45
#5 楼
使用以上所有注释,我汇编了以下符合我需要的代码:var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
我已经在iPad,Android(浏览器和Chrome)上对此进行了测试, Blackberry Playbook,iPhone 4s,Windows Phone 8,IE 10,IE 8,IE 10(带有触摸屏的Windows 8),Opera,Chrome和Firefox。
它目前在Windows Phone 7上无法运行,我还没有尚未能够找到该浏览器的解决方案。
希望有人觉得这很有用。
评论
有什么原因不能使用:function is_touch_device(){return !!(窗口中的“ ontouchstart”)|| !!(导航器中的'msmaxtouchpoints'); };
–sidonaldson
13-4-24在9:55
使用该函数可以工作,但是我通常喜欢使用上面的变量方法,因此它仅需测试一次,并且稍后在代码中进行检查时会更快。另外,我发现我需要进行测试以查看msMaxTouchPoints是否大于0,因为Windows 8上的IE 10(不带触摸屏)返回0作为msMaxTouchPoints。
–大卫
13年4月29日在13:37
在Windows 7的Firefox 32上返回true :(
– vsync
2014-11-27 14:06
Windows 8上的Firefox 33和33.1在我的系统上均正确显示false。如果将Firefox升级到最新版本,它仍然返回true吗?您是否在计算机上安装了可能使Firefox错误地认为您的计算机具有触摸功能的设备?
–大卫
2014年11月27日15:17
>>>窗口中的'ontouchstart'>>> Ubuntu上为true FF 51.0.1
–拉维·加迪亚(Ravi Gadhia)
17 Mar 3 '17 at 10:06
#6 楼
我喜欢这个:function isTouchDevice(){
return typeof window.ontouchstart !== 'undefined';
}
alert(isTouchDevice());
评论
无需使用三元表达式返回布尔值。只需使用表达式即可返回布尔值。函数isTouchDevice(){return(window.ontouchstart!==未定义); }
– Tim Vermaelen
2013年6月13日15:08
您也可以只使用:window中的var isTouch ='ontouchstart';但是,这不适用于最新的Chrome(v31),window.document中的var isTouch ='createTouch';仍在工作。
–奥利维尔
2014年1月19日15:55
如先前接受的问题的评论中所述。 “ Modernizr不会测试触摸屏。它会测试浏览器中是否存在触摸事件”。从技术上来说,您的函数是hasTouchEvents()而不是isTouchDevice()
– hexalys
2014年2月1日在3:28
请注意,仅测试touchstart的类似方法将无法将Surface识别为触摸设备,因为IE而是使用了指针事件。
–CookieMonster
2014年3月18日在13:22
也许@Nis是正确的,但是在Firefox 39中,它正确返回了false。
– Dan Dascalescu
15年7月15日在1:25
#7 楼
如果您使用Modernizr,则如前所述使用Modernizr.touch
非常容易。但是,为了安全起见,我更喜欢结合使用
Modernizr.touch
和用户代理测试。var deviceAgent = navigator.userAgent.toLowerCase();
var isTouchDevice = Modernizr.touch ||
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/) ||
deviceAgent.match(/(iemobile)/) ||
deviceAgent.match(/iphone/i) ||
deviceAgent.match(/ipad/i) ||
deviceAgent.match(/ipod/i) ||
deviceAgent.match(/blackberry/i) ||
deviceAgent.match(/bada/i));
if (isTouchDevice) {
//Do something touchy
} else {
//Can't touch this
}
如果您不使用Modernizr,则只需将上面的
Modernizr.touch
函数替换为('ontouchstart' in document.documentElement)
,还要注意,测试用户代理
iemobile
可以为您提供更广泛的检测到Microsoft移动设备的数量超过Windows Phone
。也请参阅此SO问题
评论
“做一些棘手的事情”和“做不到的事情”有很多奖励积分
–李·撒克逊人
15年12月22日在10:36
您需要多次检查同一台设备,并且在只能使用一个设备时执行多个Regexes。另外,您正在执行不区分大小写的正则表达式,但是字符串已经小写。
–凯撒索尔
16-10-19在9:39
这应该足够了:/(iphone | ipod | ipad | android | iemobile | blackberry | bada)/。test(window.navigator.userAgent.toLowerCase())
–凯撒索尔
16-10-19在9:40
有什么理由要小写或使匹配的字符不区分大小写? “ iOS”,“ Android”或“ IEMobile”什么时候使用其他大小写?
– Henrik N
17-10-24在6:06
#8 楼
我们尝试了modernizr实现,但是检测触摸事件不再是一致的(IE 10在Windows桌面上具有触摸事件,IE 11可以正常工作,因为已经删除了触摸事件并添加了指针api)。因此,只要我们不知道用户使用哪种输入类型,我们便决定将网站优化为触摸式网站。这比任何其他解决方案都更可靠。
我们的研究表明,大多数桌面用户在单击之前都会将鼠标移到屏幕上,因此我们可以检测到他们并更改其行为,然后他们才能单击或悬停任何内容。
这是我们代码的简化版本:
var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
isTouch = false;
window.removeEventListener('mousemove', mouseMoveDetector);
});
评论
当今的计算机同时具有触摸和鼠标功能……您必须与众不同。绝对必须知道它是仅触摸屏,鼠标还是两者。 3个不同的州。
– vsync
2014年11月27日14:10
是的,您是对的,但这很难。最好的情况是,您的应用程序设计为可被任何输入控制器使用,并且不在乎用户是否拥有触摸屏,鼠标,键盘或全部。
–马丁·兰兹(Martin Lantzsch)
2014年11月27日在21:24
用户的行为比用户拥有哪种设备的真实信息更有价值。当您知道用户拥有鼠标,触摸屏和键盘时-那又如何呢?处理行为(移动,触摸移动,按下按键等)。用户可以在“运行时”更改输入类型,这是一个真正的难题,当您正在开发使用8到5而无需重新加载的真实应用程序时。
–马丁·兰兹(Martin Lantzsch)
2014年11月28日在21:22
+1实用上这是对我最好的答案。例如,我有数据网格。这些数据网格将显示一个用于触摸以进行编辑的“编辑图标”,或一个用于显示更多选项的上下文菜单。如果检测到鼠标移动,则删除图标(在网格上节省空间),用户可以双击或右键单击。
– prograhammer
2015年7月9日在15:51
触摸设备上的Chrome偶尔会触发鼠标移动
– pstanton
17年7月25日在10:37
#9 楼
比检查他们是否有触摸屏要好得多,它可以检查是否正在使用它,而且检查起来也更容易。if (window.addEventListener) {
var once = false;
window.addEventListener('touchstart', function(){
if (!once) {
once = true;
// Do what you need for touch-screens only
}
});
}
#10 楼
工作小提琴我已经做到了;
function isTouchDevice(){
return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
if(isTouchDevice()===true) {
alert('Touch Device'); //your logic for touch device
}
else {
alert('Not a Touch Device'); //your logic for non touch device
}
#11 楼
即使在Windows Surface平板电脑中,这一功能也能正常工作!!!function detectTouchSupport {
msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
touchSupport = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch);
if(touchSupport) {
$("html").addClass("ci_touch");
}
else {
$("html").addClass("ci_no_touch");
}
}
#12 楼
我使用上面的代码来检测是否触摸,所以我的fancybox iframe会显示在台式计算机上而不是触摸上。我注意到,仅使用blmstr的代码时,适用于Android 4.0的Opera Mini仍在注册为非触摸设备。 (有人知道为什么吗?)我最终使用了:
<script>
$(document).ready(function() {
var ua = navigator.userAgent;
function is_touch_device() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
if ((is_touch_device()) || ua.match(/(iPhone|iPod|iPad)/)
|| ua.match(/BlackBerry/) || ua.match(/Android/)) {
// Touch browser
} else {
// Lightbox code
}
});
</script>
评论
您能否解释一下,为什么不对单个正则表达式/ iPhone | iPod | iPad | Android | BlackBerry /使用单个匹配调用?
–德米特里·科罗里奥夫(Dmitry Koroliov)
2014年4月11日在9:02
Opera Mini在Opera的服务器上而不是在设备本身上进行渲染,所以这种方式有点奇怪。
– bluesmoon
15年8月24日在15:52
#13 楼
尝试检测触摸的最大“陷阱”是在同时支持触摸和触控板/鼠标的混合设备上。即使您能够正确检测用户设备是否支持触摸,您真正需要做的就是检测用户当前使用的输入设备。这里有关于此挑战的详细记录以及可能的解决方案。基本上,确定用户只是触摸屏幕还是使用鼠标/触控板的方法是在页面上注册
touchstart
和mouseover
事件:document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"
触摸动作将触发这两个事件,尽管前者(
touchstart
)始终在大多数设备上始终优先。因此,依靠此可预测的事件序列,您可以创建一种机制,以动态地在文档根目录中添加或删除can-touch
类,以反映此时用户在文档上的当前输入类型:;(function(){
var isTouch = false //var to indicate current input type (is touch versus no touch)
var isTouchTimer
var curRootClass = '' //var indicating current document root class ("can-touch" or "")
function addtouchclass(e){
clearTimeout(isTouchTimer)
isTouch = true
if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
curRootClass = 'can-touch'
document.documentElement.classList.add(curRootClass)
}
isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
}
function removetouchclass(e){
if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
isTouch = false
curRootClass = ''
document.documentElement.classList.remove('can-touch')
}
}
document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();
更多详细信息。
#14 楼
实际上,我研究了这个问题并考虑了所有情况。因为这也是我项目中的大问题。因此,我达到以下功能,它适用于所有设备上所有浏览器的所有版本:const isTouchDevice = () => {
const prefixes = ['', '-webkit-', '-moz-', '-o-', '-ms-', ''];
const mq = query => window.matchMedia(query).matches;
if (
'ontouchstart' in window ||
(window.DocumentTouch && document instanceof DocumentTouch)
) {
return true;
}
return mq(['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''));
};
提示:毫无疑问,
isTouchDevice
仅返回boolean
值。评论
我认为您需要const IsTouchDevice =(()=> {...})();
–抢夺
9月16日15:48
@Rob,它是一个函数,它在开发人员上如何使用它。
– AmerllicA
9月16日下午16:42
#15 楼
看看这篇文章,它提供了一个非常不错的代码段,用于检测到触摸设备时执行的操作或在调用touchstart事件时应执行的操作:$(function(){
if(window.Touch) {
touch_detect.auto_detected();
} else {
document.ontouchstart = touch_detect.surface;
}
}); // End loaded jQuery
var touch_detect = {
auto_detected: function(event){
/* add everything you want to do onLoad here (eg. activating hover controls) */
alert('this was auto detected');
activateTouchArea();
},
surface: function(event){
/* add everything you want to do ontouchstart here (eg. drag & drop) - you can fire this in both places */
alert('this was detected by touching');
activateTouchArea();
}
}; // touch_detect
function activateTouchArea(){
/* make sure our screen doesn't scroll when we move the "touchable area" */
var element = document.getElementById('element_id');
element.addEventListener("touchstart", touchStart, false);
}
function touchStart(event) {
/* modularize preventing the default behavior so we can use it again */
event.preventDefault();
}
#16 楼
我会避免使用屏幕宽度来确定设备是否为触摸设备。想想Windows 8,有比699px大得多的触摸屏。Navigatior.userAgent可能会很好地覆盖假阳性。我建议您在Modernizr上检查此问题。
是否要测试设备是否支持触摸事件或是触摸设备。不幸的是,那不是同一回事。
#17 楼
不,不可能。给出的出色答案永远都是局部的,因为任何给定的方法都会产生误报和误报。由于OS API,即使浏览器也不总是知道是否存在触摸屏,并且在浏览器会话期间,尤其是使用KVM类型的布置时,事实可能会发生变化。在此出色的工具中查看更多详细信息文章:
http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
文章建议您重新考虑使您成为现实的假设想检测触摸屏,可能是错误的。 (我检查了自己的应用程序,但我的假设确实是错误的!)
本文的结论是:
对于布局,假定每个人都有触摸屏。鼠标用户可以使用大型UI控件,而触摸用户可以使用小型
控件。悬停状态也是如此。
对于事件和交互,假设任何人都可以拥有触摸屏。
相互实现键盘,鼠标和触摸交互,
确保彼此之间都不会阻塞其他。
#18 楼
这些工具很多,但要么需要jQuery,要么需要javascript linter抱怨语法。考虑到您的第一个问题需要一种“ JavaScript”(不是jQuery,不是Modernizr)的解决方案,这是一个每次都能使用的简单函数。function isTouchDevice() {
return !!window.ontouchstart;
}
console.log(isTouchDevice());
我要提到的最后一个好处是该代码与框架和设备无关。享受吧!
#19 楼
var isTouchScreen = 'createTouch' in document;
或
var isTouchScreen = 'createTouch' in document || screen.width <= 699 ||
ua.match(/(iPhone|iPod|iPad)/) || ua.match(/BlackBerry/) ||
ua.match(/Android/);
我想将是更彻底的检查。
评论
最好注意到ua指向navigator.userAgent。同样,如果有人在非全屏模式下打开浏览器,则按屏幕宽度进行的检测也会给出错误的结果。
–HoLyVieR
2011年11月5日,下午3:45
#20 楼
Chrome 24现在似乎支持触摸事件,可能适用于Windows8。因此此处发布的代码不再起作用。现在,我不再尝试检测浏览器是否支持触摸,而是绑定触摸和单击事件,并确保只调用了一个:myCustomBind = function(controlName, callback) {
$(controlName).bind('touchend click', function(e) {
e.stopPropagation();
e.preventDefault();
callback.call();
});
};
称呼它为
myCustomBind('#mnuRealtime', function () { ... });
希望有帮助!
评论
相关线程,stackoverflow.com / questions / 12566306 /…
–Air
2014年5月12日15:10
#21 楼
除适用于桌面的Firefox外,所有受支持的浏览器始终为TRUE,因为即使您不单击“触摸按钮”,Firefox的桌面也支持开发人员的响应式设计!我希望Mozilla会在下一版本中修复此问题。
我正在使用Firefox 28桌面。
function isTouch()
{
return !!("ontouchstart" in window) || !!(navigator.msMaxTouchPoints);
}
评论
它仍然是32.0版,他们还没有修复!疯。为什么这不能切换?这总是返回true :(
– vsync
2014年11月27日14:12
#22 楼
jQuery v1.11.3提供的答案中有很多很好的信息。但是,最近,我花了很多时间尝试将所有内容实际结合到一个可行的解决方案中,以完成两件事:检测正在使用的设备是触摸屏类型的设备。
检测到设备被窃听。
除了这篇文章和使用Javascript检测触摸屏设备之外,我发现Patrick Lauke的这篇文章非常有帮助:https://hacks.mozilla.org/ 2013/04 /检测触摸为什么的方式/
这是代码...
$(document).ready(function() {
//The page is "ready" and the document can be manipulated.
if (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0))
{
//If the device is a touch capable device, then...
$(document).on("touchstart", "a", function() {
//Do something on tap.
});
}
else
{
null;
}
});
重要!
*.on( events [, selector ] [, data ], handler )
方法需要具有一个选择器,通常是一个元素,可以处理“ touchstart”事件或与触摸相关的任何其他事件。在这种情况下,它是超链接元素“ a”。现在,您无需处理JavaScript中的常规鼠标单击操作,因为您可以使用CSS通过选择器的选择器来处理这些事件。超链接“ a”元素如下:
/* unvisited link */
a:link
{
}
/* visited link */
a:visited
{
}
/* mouse over link */
a:hover
{
}
/* selected link */
a:active
{
}
注意:还有其他选择器...
#23 楼
问题由于混合使用触摸和鼠标输入的混合设备,您需要能够动态更改状态/变量,该状态/变量控制如果用户是触摸用户,是否应该运行一段代码。
触摸设备也会在点击时触发
mousemove
。解决方案
等待直到触发
touchstart
事件,然后将其设置为true。 如果触发touchstart,则添加一个mousemove处理程序。
如果两次mousemove事件触发之间的时间少于20ms,则假定它们使用鼠标作为输入。删除事件,因为它不再需要,并且mousemove对于鼠标设备来说是一个昂贵的事件。
再次触发touchstart(用户重新使用touch)后,该变量将设置为true。并重复此过程,以便以动态方式确定它。如果奇迹般快速地将mousemove触发两次触摸(在我的测试中,几乎不可能在20ms内触发),则下一次touchstart会将其设置为true。
在Safari iOS和Chrome上进行了测试适用于Android。
注意:不能100%确定MS Surface等的指针事件。
Codepen演示
const supportsTouch = 'ontouchstart' in window;
let isUsingTouch = false;
// `touchstart`, `pointerdown`
const touchHandler = () => {
isUsingTouch = true;
document.addEventListener('mousemove', mousemoveHandler);
};
// use a simple closure to store previous time as internal state
const mousemoveHandler = (() => {
let time;
return () => {
const now = performance.now();
if (now - time < 20) {
isUsingTouch = false;
document.removeEventListener('mousemove', mousemoveHandler);
}
time = now;
}
})();
// add listeners
if (supportsTouch) {
document.addEventListener('touchstart', touchHandler);
} else if (navigator.maxTouchPoints || navigator.msMaxTouchPoints) {
document.addEventListener('pointerdown', touchHandler);
}
#24 楼
我在jQuery mobile 1.0.1中使用:if(jQuery.support.touch){
alert('Touch enabled');
}
#25 楼
我还为如何在Javascript中检测页面是否在触摸屏设备上显示而在不同选项上作了很多努力。IMO,到目前为止,尚不存在真正的选项来正确检测该选项。 >浏览器要么报告台式机上的触摸事件(因为操作系统可能支持触摸),要么某些解决方案不能在所有移动设备上运行。
最后,我意识到我一直在关注从一开始就使用错误的方法:
如果我的页面在触摸和非触摸设备上看起来很相似,那么我也许根本不必担心检测该属性:
我的情况是停用工具提示触摸设备上的按钮,因为它们会导致双击,因此我希望单击一下即可激活按钮。
我的解决方案是重构视图,以便在按钮上不需要工具提示,并且最后,我不需要使用所有都有缺点的方法从Javascript中检测触摸设备。
#26 楼
您可以安装现代化器并使用简单的触摸事件。这非常有效,并且可以在我测试过的所有设备(包括Windows表面)上使用!我创建了jsFiddle
function isTouchDevice(){
if(Modernizr.hasEvent('touchstart') || navigator.userAgent.search(/Touch/i) != -1){
alert("is touch");
return true;
}else{
alert("is not touch");
return false;
}
}
评论
欢迎来到SO!单独的代码(如未注释的代码)很少构成答案。您可以通过添加摘要说明来改善此答案。
– ebarr
2014年5月21日在10:02
#27 楼
实际的答案似乎是考虑上下文的答案:1)公共站点(无登录)
对UI进行编码以将这两个选项一起使用。
2)登录站点
捕获是否在登录表单上发生了鼠标移动,并将其保存到隐藏的输入中。该值与登录凭据一起传递并添加到用户的会话中,因此可以在会话期间使用。
仅添加到登录页面的Jquery:
$('#istouch').val(1); // <-- value will be submitted with login form
if (window.addEventListener) {
window.addEventListener('mousemove', function mouseMoveListener(){
// Update hidden input value to false, and stop listening
$('#istouch').val(0);
window.removeEventListener('mousemove', mouseMoveListener);
});
}
(+1回复@Dave Burt,+ 1回复@Martin Lantzsch)
#28 楼
没错,因此在检测触摸/非触摸设备方面存在巨大争议。窗口输入板的数量和输入板的大小正在增加,这给我们的Web开发人员带来了另一组头痛。我已经使用并测试了blmstr的菜单答案。菜单的工作方式如下:当页面加载时,脚本将检测这是触摸设备还是非触摸设备。基于此菜单可以在悬停(非触摸)或单击/轻击(触摸)上运行。
在大多数情况下,blmstr的脚本似乎运行得很好(特别是2018年的脚本)。但是仍然有一个设备在不触摸时会被检测为触摸,反之亦然。
由于这个原因,我做了一些挖掘工作,并且由于本文的缘故,我将blmstr的第4个脚本中的几行替换为:
function is_touch_device4() {
if ("ontouchstart" in window)
return true;
if (window.DocumentTouch && document instanceof DocumentTouch)
return true;
return window.matchMedia( "(pointer: coarse)" ).matches;
}
alert('Is touch device: '+is_touch_device4());
console.log('Is touch device: '+is_touch_device4());
由于锁定设备的供应有限,因此无法对其进行测试,但是到目前为止,上述方法都非常有效。 )可以确认脚本是否可以正常工作。
现在就支持指针:似乎支持粗媒体查询。我在上面保留了这些行,因为在移动firefox上遇到了(由于某种原因)问题,但是媒体查询上方的行可以解决问题。
谢谢
#29 楼
我认为最好的方法是:var isTouchDevice =
(('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0));
if(!isTouchDevice){
/* Code for touch device /*
}else{
/* Code for non touch device */
}
评论
navigator.MaxTouchPoints-> navigator.maxTouchPoints
–李在浩(Jaeho Lee)
11月11日19:29
#30 楼
扩展jQuerysupport
对象:jQuery.support.touch = 'ontouchend' in document;
现在您可以在任何地方检查它,就像这样:
评论
这是document.documentElement中var x ='touchstart'的更好方法; console.log(x)//如果支持则返回true //否则返回false如果仍然出现新技术,为什么要保护此线程?