Javascript 如何针对触摸设备优化网站
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2607248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to optimize website for touch devices
提问by gregers
On a touch device like iPhone/iPad/Android it can be difficult to hit a small button with your finger. There is no cross-browser way to detect touch devices with CSS media queries that I know of. So I check if the browser has support for Javascript touch events. Until now, other browsers haven't supported them, but the latest Google Chrome on dev channel enabled touch events(even for non touch devices). And I suspect other browser makers will follow, since laptops with touch screens are coming. Update: It was a bug in Chrome, so now the JavaScript detection works again.
在 iPhone/iPad/Android 等触控设备上,可能很难用手指点击一个小按钮。据我所知,没有跨浏览器的方式来检测带有 CSS 媒体查询的触摸设备。所以我检查浏览器是否支持 Javascript 触摸事件。到目前为止,其他浏览器还不支持它们,但开发频道上最新的谷歌浏览器启用了触摸事件(即使对于非触摸设备)。而且我怀疑其他浏览器制造商会效仿,因为带有触摸屏的笔记本电脑即将问世。更新:这是 Chrome 中的一个错误,所以现在 JavaScript 检测再次工作。
This is the test I use:
这是我使用的测试:
function isTouchDevice() {
return "ontouchstart" in window;
}
The problem is that this only tests if the browser has support for touch events, not the device.
问题是这仅测试浏览器是否支持触摸事件,而不是设备。
Does anyone know of The Correct[tm] way of giving touch devices better user experience? Other than sniffing user agent.
有没有人知道为触摸设备提供更好的用户体验的正确 [tm] 方式?除了嗅探用户代理。
Mozilla has a media query for touch devices. But I haven't seen anything like it in any other browser: https://developer.mozilla.org/En/CSS/Media_queries#-moz-touch-enabled
Mozilla 有一个针对触摸设备的媒体查询。但我还没有在任何其他浏览器中看到类似的东西:https: //developer.mozilla.org/En/CSS/Media_queries#-moz-touch-enabled
Update: I want to avoid using a separate page/site for mobile/touch devices. The solution has to detect touch devices with object detection or similar from JavaScript, or include a custom touch-CSS without user agent sniffing! The main reason I asked, was to make sure it's not possible today, before I contact the css3 working group. So please don't answer if you can't follow the requirements in the question ;)
更新:我想避免为移动/触摸设备使用单独的页面/站点。该解决方案必须使用 JavaScript 中的对象检测或类似方法来检测触摸设备,或者包含自定义的触摸 CSS,而无需用户代理嗅探!我问的主要原因是在我联系 css3 工作组之前确保今天不可能。因此,如果您不能遵循问题中的要求,请不要回答;)
采纳答案by u7867
It sounds to me like you want to have a touch-screen-friendly option, to cover the following scenarios:
在我看来,您想要一个适合触摸屏的选项,以涵盖以下场景:
- iPhone-like devices: small screen, touch only
- Small screens, no touch (you didn't mention this one)
- Large screens, no touch (i.e. conventional computers)
- Touch-screen-enabled large screens such as iPad, notebooks/pcs with touch screens.
- 类似 iPhone 的设备:小屏幕,仅触控
- 小屏,无触控(你没提这个)
- 大屏幕,无触摸(即传统电脑)
- 支持触摸屏的大屏幕,如 iPad、带触摸屏的笔记本电脑/个人电脑。
For case 1 and 2 you will probably need a separate site or a CSS file that eliminates lots of unnecessary content and makes things larger and easier to read/navigate. If you care about case #2 then as long as the links/buttons on the page are keyboard-navigable then case 1 and 2 are equivalent.
对于情况 1 和 2,您可能需要一个单独的站点或 CSS 文件,以消除大量不必要的内容并使内容更大更易于阅读/导航。如果您关心案例 #2,那么只要页面上的链接/按钮是可通过键盘导航的,那么案例 1 和案例 2 是等效的。
For case 3 you have your normal website. For case 4 it sounds like you want clickable things to be bigger or easier to touch. If it's not possible to simply make everything bigger for all users, an alternate style-sheet can provide you with the touch-friendly layout changes.
对于案例 3,您拥有正常的网站。对于案例 4,听起来您希望可点击的东西更大或更容易触摸。如果不能简单地为所有用户放大所有内容,替代样式表可以为您提供触摸友好的布局更改。
The easiest thing to do is provide a link to the touch-screen-version of the site somewhere on the page. For well-known touch devices such as iPad you can sniff the user agent and set the touch stylesheet as the default. However I'd consider making this the default for everyone; if your design looks good on the iPad it should look acceptably good on any notebook. Your mouse users with less-than-stellar clicking skills will be pleased to find bigger click targets, especially if you add appropriate :hoveror mouseovereffects to let users know that things are clickable.
最简单的方法是在页面某处提供指向该网站触摸屏版本的链接。对于众所周知的触摸设备,例如 iPad,您可以嗅探用户代理并将触摸样式表设置为默认值。但是我会考虑将其设为每个人的默认设置;如果您的设计在 iPad 上看起来不错,那么它在任何笔记本电脑上都应该看起来不错。点击技能不太好的鼠标用户会很高兴找到更大的点击目标,特别是如果您添加适当的:hover或mouseover效果让用户知道东西是可点击的。
I know you said you don't want to sniff user-agents. But I'd contend that at this time the state of browser support for this is in too much flux to worry about the "Correct" way to do it. Browsers will eventually provide the information that you need, but you will probably find that it will be years before this information is ubiquitous.
我知道你说过你不想嗅探用户代理。但我认为此时浏览器对此的支持状态变化太大,无法担心“正确”的方式来做到这一点。浏览器最终会提供您需要的信息,但您可能会发现,要让这些信息无处不在还需要数年时间。
回答by gregers
Good news! The editor draft of CSS4 Media Querieshave included a new media feature 'pointer'.
好消息!CSS4 Media Queries的编辑器草案包含了一个新的媒体功能“指针”。
Typical examples of a ‘fine' pointing system are a mouse, a track-pad or a stylus-based touch screen. Finger-based touch screens would qualify as ‘coarse'.
“精细”指点系统的典型示例是鼠标、触控板或基于手写笔的触摸屏。基于手指的触摸屏将被视为“粗糙”。
/* Make radio buttons and check boxes larger if we
have an inaccurate pointing device */
@media (pointer:coarse) {
input[type="checkbox"], input[type="radio"] {
min-width:30px;
min-height:40px;
background:transparent;
}
}
It's also possible to test the media query from JavaScript:
也可以从 JavaScript 测试媒体查询:
var isCoarsePointer = (window.matchMedia &&
matchMedia("(pointer: coarse)").matches);
Updated Feb. 11th. 2013On Windows 8 recent versions of Chrome (version 24+) detect touch-hardware when launching the application and expose touch events. Unfortunately if "pointer:coarse" returns false, there is no way to know if it's because pointer media queries are not implemented or because there is a fine pointer. WebKit haven't implemented"pointer:fine" yet, so we can't check that either.
2 月 11 日更新。2013在 Windows 8 上最新版本的 Chrome(版本 24+)在启动应用程序时检测触摸硬件并公开触摸事件。不幸的是,如果 "pointer:coarse" 返回 false,则无法知道是因为没有实现指针媒体查询,还是因为有一个细指针。WebKit还没有实现“pointer:fine”,所以我们也不能检查。
Update Sept. 26th. 2012Tested in Safari on iOS6 and Chrome on Android 4.1.1 and it's not there yet. 'pointer' and 'hover' media-queries landed in WebKitMay 30th. According to the User-Agent, Safari uses WebKit branch 536.26from April 25th, and Chrome on Android uses and even older one (535.19). Not sure WebKit branches from User-Agent strings are to be trusted, but my test pageis not able to detect pointer media queries either. The implementation from Mayonly implements the pointer media query for touch devices, so pointer: fine won't work for devices with a mouse.
9 月 26 日更新。2012在 iOS6 上的 Safari 和 Android 4.1.1 上的 Chrome 中进行了测试,目前还没有。'pointer' 和 'hover' 媒体查询于5 月 30 日登陆 WebKit。根据 User-Agent 的说法,Safari从 4 月 25 日起使用 WebKit 分支536.26,Android 上的 Chrome 使用甚至更旧的分支(535.19)。不确定来自 User-Agent 字符串的 WebKit 分支是否可信,但我的测试页面也无法检测指针媒体查询。May的实现仅实现了触摸设备的指针媒体查询,因此 pointer: fine 不适用于带有鼠标的设备。
回答by Michael Hixson
I don't know if a standardized media query like Mozilla's will solve the problem by itself. Like one of the Chromium developers said in that discussion you linked, the presence of touch event support in the browser doesn't mean touch events can or will fire, or even if they do, that the user will only want to interact via touch input. Likewise, the presence of touch input support in the device doesn't mean the user will use that method of input - perhaps the device supports mouse, keyboard, and touch input and the user prefers the mouse or some combination of the three input types.
我不知道像 Mozilla 这样的标准化媒体查询是否会自行解决问题。就像一位 Chromium 开发人员在您链接的讨论中所说的那样,浏览器中触摸事件支持的存在并不意味着触摸事件可以或将触发,或者即使触发,用户也只想通过触摸输入进行交互. 同样,设备中支持触摸输入并不意味着用户将使用该输入方法——也许设备支持鼠标、键盘和触摸输入,而用户更喜欢鼠标或三种输入类型的某种组合。
I agree with the Chromium developer that supporting touch events was not a bug in the browser. A good browser should support touch events because it might be installed on a device that supports touch input. It's the website developer's fault that he took the event support to mean the user would be interacting via touch.
我同意 Chromium 开发人员的观点,即支持触摸事件不是浏览器中的错误。一个好的浏览器应该支持触摸事件,因为它可能安装在支持触摸输入的设备上。网站开发人员的错,他认为事件支持意味着用户将通过触摸进行交互。
It seems we need to know two things: (1) What are all the supported input types on the device (2) What are all the supported event types in the browser
看来我们需要知道两件事:(1)设备上支持的所有输入类型是什么(2)浏览器中支持的所有事件类型是什么
Since we don't know #1 right now, there is one approach proposed by PPK of quirksmode that I like. He talks about it here: http://www.quirksmode.org/blog/archives/2010/02/do_we_need_touc.html#link4
由于我们现在不知道 #1,因此我喜欢 quirksmode 的 PPK 提出的一种方法。他在这里谈论它:http: //www.quirksmode.org/blog/archives/2010/02/do_we_need_touc.html#link4
Basically, listen for touch events and mouse events, and when they happen, set up the UI accordingly. Obviously that's limiting to the developer. I don't think it's a valid approach to your problem with link size because you don't want to wait for interaction to alter the UI. The whole point is to present a different UI (a larger/smaller link) before any interaction occurs.
基本上,监听触摸事件和鼠标事件,当它们发生时,相应地设置 UI。显然,这仅限于开发人员。我认为这不是解决链接大小问题的有效方法,因为您不想等待交互来更改 UI。重点是在任何交互发生之前呈现不同的 UI(更大/更小的链接)。
I hope you make your proposal and it gets included in CSS3. Until then, as much as it pains me to say it, user agent sniffing looks like the best approach.
我希望你提出你的建议并且它被包含在 CSS3 中。在那之前,尽管我很难说,但用户代理嗅探看起来是最好的方法。
p.s. I hope hope hope someone comes here and proves me wrong
ps我希望希望有人来证明我错了
回答by gregers
Google Chrome has a command line switch for enabling touch events. Disabled by default. So until they enable them for everyone again (hopefully they won't), it's possible to detect touch with the help of javascript like I described in the question..
谷歌浏览器有一个用于启用触摸事件的命令行开关。默认禁用。因此,在他们再次为每个人启用它们之前(希望他们不会),可以像我在问题中描述的那样借助 javascript 检测触摸。.
Update jun 3 2010: This actually got into the stable version on 25th of May 2010 :( Don't know it it was a mistake or not.
2010 年 6 月 3 日更新:这实际上是在 2010 年 5 月 25 日进入稳定版本:( 不知道这是不是一个错误。
Have discussed the issue on the w3c mailing list, but I doubt anything will happen very soon. http://lists.w3.org/Archives/Public/www-style/2010May/0411.htmlThey might discuss this during TPAC in November.
已经在 w3c 邮件列表上讨论过这个问题,但我怀疑很快就会发生任何事情。http://lists.w3.org/Archives/Public/www-style/2010May/0411.html他们可能会在 11 月的 TPAC 期间讨论这个问题。
Update sep 30 2010: Supposedly fixed in Chrome 6. Haven't had time to downgrade to stable yet to verify. Since Chrome upgrade automatically this problem should already be gone :)
2010 年 9 月 30 日更新:据说已在 Chrome 6 中修复。还没有时间降级到稳定版尚待验证。由于 Chrome 自动升级,这个问题应该已经消失了:)
Read this if you're considering using media queries: http://www.cloudfour.com/css-media-query-for-mobile-is-fools-gold/and http://www.quirksmode.org/blog/archives/2010/09/more_about_medi.html
如果您正在考虑使用媒体查询 ,请阅读此内容:http: //www.cloudfour.com/css-media-query-for-mobile-is-fools-gold/和http://www.quirksmode.org/blog/档案/2010/09/more_about_medi.html
Update may 16th 2011: W3C is now working on a Touch Events specification, but more or less refusedto hide touch events for terminals without touch hardware. So don't expect the touch event detection to work for long.
2011 年 5 月 16 日更新:W3C 现在正在制定触摸事件规范,但或多或少拒绝为没有触摸硬件的终端隐藏触摸事件。所以不要指望触摸事件检测能长时间工作。
Update june 6th 2012: The W3C CSS4 Media Queries (Editors Draft) spec have something very interesting. See my separate answerabout this.
2012 年 6 月 6 日更新:W3C CSS4 媒体查询(编辑器草案)规范有一些非常有趣的东西。请参阅我对此的单独回答。
回答by Dave Gregory
No, there is no such thing.
CSS has the screen size option, which will allow you to optimize layout, but that's all.
There is also media="handheld"but that also doesn't apply to your requirements.
不,没有这样的事情。CSS 具有屏幕大小选项,可让您优化布局,仅此而已。还有,media="handheld"但这也不适用于您的要求。
Feature detection might work using javascript, however, there are issues with different events for different devices. PPK (the man behind quirksmode.org) is doing a huge amount of work checking what javascript is possible for each mobile/handheld device, and it's proving that nothing seems to be standard with these devices and yet this STILL doesn't apply to your requirement for touch laptop devices.
(honestly I dont know why you are concerned about a device that isn't even out yet, be pragmatic and worry about it once it's here and you can test it)
功能检测可能使用 javascript 工作,但是,不同设备的不同事件存在问题。PPK(quirksmode.org 背后的人)正在做大量的工作来检查每个移动/手持设备可以使用什么 javascript,这证明这些设备似乎没有任何标准,但这仍然不适用于您触摸笔记本电脑设备的要求。
(老实说,我不知道为什么您会担心尚未推出的设备,务实并担心它一旦出现就可以测试它)
PPK's work on mobile browser and touch events, will save you hours. Check it out here
PPK 在移动浏览器和触摸事件方面的工作将为您节省数小时。检查出来这里
回答by Divya Manian
Apple has TouchEvents defined only for iPhone OSFWIW
Apple仅为 iPhone OSFWIW定义了 TouchEvents
回答by sleske
Not a complete solution, but you might want to simply outright avoid any small buttons. While small buttons are more of a usability problem on touch devices, they are always hard to use, even with a big screen & mouse.
不是一个完整的解决方案,但您可能只想完全避免使用任何小按钮。虽然小按钮在触摸设备上更容易出现可用性问题,但即使使用大屏幕和鼠标,它们也总是难以使用。
If you just pay attention to using suitably big buttons with enough space between them, everyone will benefit. Plus, it will force you not to clutter your interface with too many small buttons :-).
如果您只是注意使用适当的大按钮,它们之间有足够的空间,每个人都会受益。另外,它会迫使你不要用太多的小按钮来弄乱你的界面:-)。
回答by Ismael Miguel
try using tables and make a full cell to be a link... i'm working on that in my website... it's not working well so far... but you might find a way... on this way, no need to overload your website with javascript and functionality detection... you can give it a relative size instread of a fixed size... and in this way, your website can be viewed in a desktop as is viewed in a iphone... think about this idea... any sugestion is apreciated...
尝试使用表格并制作一个完整的单元格作为链接......我正在我的网站上处理这个......到目前为止它工作得不好......但你可能会找到一种方法......通过这种方式,不需要使用 javascript 和功能检测超载您的网站...您可以给它一个固定大小的相对大小 instread...这样,您的网站可以在桌面上查看,就像在 iphone 中查看一样...想想这个想法......任何sugestion都是apreciated......
回答by Rick Byers
See http://crbug.com/136119for support for adding pointer:fine in Chrome. It is actually possible to detect whether pointer:coarse is supported (to distinguish unset from not supported) - just create the media query yourself and test in javascript whether it parsed properly.
有关在 Chrome 中添加指针的支持,请参阅http://crbug.com/136119。实际上可以检测是否支持 pointer:coarse(以区分未设置和不支持) - 只需自己创建媒体查询并在 javascript 中测试它是否正确解析。
Eg., today "@media (pointer:coarse)" in Chrome shows up:
例如,今天 Chrome 中的“@media (pointer:coarse)”出现了:
> document.styleSheets[0].rules[5].media[0]
"(pointer: coarse)"
But unsupported bogus values like "@media (pointer:other)" don't:
但是像“@media (pointer:other)”这样不受支持的虚假值不会:
> document.styleSheets[0].rules[8].media[0]
"not all"
回答by Jonah
If you are using PHP, this is a good solution:
如果您使用的是 PHP,这是一个很好的解决方案:
http://chrisschuld.com/projects/browser-php-detecting-a-users-browser-from-php/
http://chrisschuld.com/projects/browser-php-detecting-a-users-browser-from-php/
You can detect whether the browser is a phone from the serverside by sniffing the browser request details, and if so, display alternative/extra stylesheets/js/html
您可以通过嗅探浏览器请求的详细信息从服务器端检测浏览器是否是手机,如果是,则显示替代/额外样式表/js/html

