scr*_*key 392 javascript jquery touch
我编写了一个jQuery插件,可以在桌面和移动设备上使用.我想知道是否有一种方法可以检测设备是否具有触摸屏功能.我正在使用jquery-mobile.js来检测触摸屏事件,它可以在iOS,Android等上运行,但我也想根据用户的设备是否有触摸屏来编写条件语句.
那可能吗?
bol*_*er2 634
你尝试过使用这个功能吗?(这与Modernizr过去常用的相同.)
function is_touch_device() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
console.log(is_touch_device());Run Code Online (Sandbox Code Playgroud)
更新1
document.createEvent("TouchEvent")已经开始回归true最新的铬(第17节).Modernizr不久前更新了这个.检查Modernizr测试在这里.
像这样更新你的功能,使其工作:
function is_touch_device1() {
return 'ontouchstart' in window;
}
console.log(is_touch_device1());Run Code Online (Sandbox Code Playgroud)
更新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());Run Code Online (Sandbox Code Playgroud)
更新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());Run Code Online (Sandbox Code Playgroud)
更新2018年
时间流逝,有新的更好的方法来测试这个.我基本上提取并简化了Modernizr的检查方式:
function is_touch_device4() {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var mq = function(query) {
return window.matchMedia(query).matches;
}
if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return mq(query);
}
console.log(is_touch_device4());Run Code Online (Sandbox Code Playgroud)
他们在这里使用的是非标准的touch-enabled媒体查询功能,我认为这有点奇怪和不好的做法.但是,嘿,在现实世界中,我猜它有效.将来(当所有人都支持它们时)这些媒体查询功能可以给你相同的结果:pointer和hover.
有关解释触摸检测问题的优秀文章,请参阅: Stu Cox:您无法检测到触摸屏.
Ala*_*mas 138
更新:在将整个功能检测库拉入项目之前,请先阅读下面的blmstr答案.检测实际触摸支持更复杂,而Modernizr仅涵盖基本用例.
Modernizr是一种非常轻巧的方式,可以在任何网站上进行各种功能检测.
它只是为每个功能的html元素添加类.
然后,您可以在CSS和JS中轻松地定位这些功能.例如:
html.touch div {
width: 480px;
}
html.no-touch div {
width: auto;
}
Run Code Online (Sandbox Code Playgroud)
和Javascript(jQuery示例):
$('html.touch #popup').hide();
Run Code Online (Sandbox Code Playgroud)
Mat*_*tow 118
由于Modernizr在Windows Phone 8/WinRT上没有检测到IE10,因此一个简单的跨浏览器解决方案是:
var supportsTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints;
Run Code Online (Sandbox Code Playgroud)
您只需要检查一次,因为设备不会突然支持或不支持触摸,因此只需将其存储在变量中,这样您就可以更有效地使用它多次.
Dav*_*vid 36
使用上面的所有评论,我汇总了以下代码,以满足我的需求:
var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0));
Run Code Online (Sandbox Code Playgroud)
我在iPad,Android(浏览器和Chrome),Blackberry Playbook,iPhone 4s,Windows Phone 8,IE 10,IE 8,IE 10(带触摸屏的Windows 8),Opera,Chrome和Firefox上进行了测试.
它目前在Windows Phone 7上失败,但我还没有找到该浏览器的解决方案.
希望有人觉得这很有用.
Ben*_*uer 20
我喜欢这一个:
function isTouchDevice(){
return typeof window.ontouchstart !== 'undefined';
}
alert(isTouchDevice());
Run Code Online (Sandbox Code Playgroud)
小智 17
如果你使用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
}
Run Code Online (Sandbox Code Playgroud)
如果你不使用Modernizr,你可以简单地用Modernizr.touch上面的函数替换('ontouchstart' in document.documentElement)
另请注意,测试用户代理iemobile将为您提供比检测到的更广泛的Microsoft移动设备Windows Phone.
Bla*_*bam 16
由于引入了交互媒体功能,您可以轻松做到:
if(window.matchMedia("(pointer: coarse)").matches) {
// touchscreen
}
Run Code Online (Sandbox Code Playgroud)
https://www.w3.org/TR/mediaqueries-4/#descdef-media-any-pointer
更新(由于评论):上述解决方案是检测“粗指针”(通常是触摸屏)是否是主要输入设备。如果您想确定某个设备(例如鼠标)是否也具有触摸屏,则可以any-pointer: coarse改用它。
有关更多信息,请参见此处:检测浏览器没有鼠标并且仅是触摸式
Mar*_*sch 14
我们尝试了modernizr实现,但检测到触摸事件不再一致(IE 10在Windows桌面上有触摸事件,IE 11可以工作,因为已经删除了触摸事件并添加了指针api).
因此,只要我们不知道用户的输入类型,我们就决定将网站优化为触摸网站.这比任何其他解决方案更可靠.
我们的研究表明,大多数桌面用户在点击之前用鼠标移动到屏幕上,因此我们可以在他们点击或悬停任何内容之前检测它们并改变行为.
这是我们代码的简化版本:
var isTouch = true;
window.addEventListener('mousemove', function mouseMoveDetector() {
isTouch = false;
window.removeEventListener('mousemove', mouseMoveDetector);
});
Run Code Online (Sandbox Code Playgroud)
我这样做了;
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
}
Run Code Online (Sandbox Code Playgroud)
有什么比检查他们是否有触摸屏更好,是检查他们是否使用它,加上更容易检查.
if (window.addEventListener) {
var once = false;
window.addEventListener('touchstart', function(){
if (!once) {
once = true;
// Do what you need for touch-screens only
}
});
}
Run Code Online (Sandbox Code Playgroud)
我认为最好的方法是:
var isTouchDevice =
(('ontouchstart' in window) ||
(navigator.maxTouchPoints > 0) ||
(navigator.msMaxTouchPoints > 0));
if(!isTouchDevice){
/* Code for touch device /*
}else{
/* Code for non touch device */
}
Run Code Online (Sandbox Code Playgroud)
这个甚至在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");
}
}
Run Code Online (Sandbox Code Playgroud)
查看这篇文章,它提供了一个非常好的代码片段,说明检测到触摸设备时要执行的操作或调用 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();
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我使用上面的代码片段来检测是否触摸,所以我的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>
Run Code Online (Sandbox Code Playgroud)
小智 5
其中许多都可以工作,但要么需要 jQuery,要么 javascript linter 抱怨语法。考虑到您最初的问题要求使用“JavaScript”(不是 jQuery,不是 Modernizr)方法来解决这个问题,这里有一个每次都有效的简单函数。它也是尽可能少的。
function isTouchDevice() {
return !!window.ontouchstart;
}
console.log(isTouchDevice());
Run Code Online (Sandbox Code Playgroud)
我要提到的最后一个好处是该代码与框架和设备无关。享受!
不,这是不可能的。给出的优秀答案只是片面的,因为任何给定的方法都会产生误报和漏报。由于操作系统 API,即使浏览器也不总是知道触摸屏是否存在,并且事实可能会在浏览器会话期间发生变化,尤其是在 KVM 类型的安排中。
请参阅这篇优秀文章中的更多详细信息:
http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
该文章建议您重新考虑让您想要检测触摸屏的假设,它们可能是错误的。(我检查了我自己的应用程序,我的假设确实是错误的!)
文章的结论是:
对于布局,假设每个人都有触摸屏。鼠标用户使用大型 UI 控件比触摸用户使用小型 UI 控件更容易。悬停状态也是如此。
对于事件和交互,假设任何人都可能有触摸屏。实现键盘、鼠标和触摸交互,确保不会相互阻塞。
尝试检测触摸的最大“问题”是在支持触摸和触控板/鼠标的混合设备上。即使您能够正确检测用户的设备是否支持触摸,您真正需要做的是检测用户当前使用的输入设备。此处详细记录了此挑战和可能的解决方案。
基本上确定用户是触摸屏幕还是使用鼠标/触控板的方法是在页面上同时注册 atouchstart和mouseover事件:
document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first
document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"
Run Code Online (Sandbox Code Playgroud)
触摸操作将触发这两个事件,尽管前者 ( 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
})();
Run Code Online (Sandbox Code Playgroud)
更多细节在这里。
实际上,我研究了这个问题并考虑了所有情况。因为这也是我项目中的一个大问题。所以我达到了以下功能,它适用于所有设备上所有浏览器的所有版本:
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(''));
};
Run Code Online (Sandbox Code Playgroud)
提示:当然,isTouchDevice只是返回boolean值。
| 归档时间: |
|
| 查看次数: |
354103 次 |
| 最近记录: |