是否有可能强迫忽略:iPhone / iPad用户的hover伪类?
我在我的网站上有一些CSS菜单扩展:hover (不含js) 
 这在iDevices上以半破解的方式工作,例如,轻击将激活:hover规则并展开菜单,但是在其他地方轻击不会删除:hover 。 另外,如果在元素内部存在链接:hover ,则必须点击两次以激活链接(第一次点击触发:hover ,第二次点击触发链接)。 
 我已经能够通过绑定touchstart事件在iPhone上很好地工作。 
 问题是,有时移动Safari仍然会select从CSS触发:hover规则, 而不是我的touchstart事件! 
 我知道这是问题,因为当我禁用CSS中的所有手动:hover规则时,移动Safari浏览器效果很好(但是常规浏览器显然不再)。 
 有没有办法dynamic“取消” :hover当用户在移动Safari浏览器的某些元素的:hover规则? 
在这里查看和比较iOS行为: http : //jsfiddle.net/74s35/3/注意:只有一些css属性触发双击行为,例如display:none; 但不是背景:红色; 或文字修饰:下划线;
我发现iPhone / iPad Safari中“:hover”是不可预知的。 有时点击元素使元素“:hover”,而有时它漂移到其他元素。
就目前而言,我只是在身体上有一个“不触摸”的课程。
 <body class="yui3-skin-sam no-touch"> ... </body> 
在“.no-touch”下面有“:hover”的所有CSS规则:
 .no-touch my:hover{ color: red; } 
在页面的某个地方,我有JavaScript从身体删除非触摸类。
 if ('ontouchstart' in document) { Y.one('body').removeClass('no-touch'); } 
这看起来不太完美,但它仍然有效。
  :hover在这里不是问题。  iOS的Safari遵循一个非常奇怪的规则。 它首先触发mouseover和mousemove ; 如果在这些事件中有任何改变,“点击”和相关的事件不会被解雇: 
  
 
 似乎包含了mouseenter和mouseleave ,虽然它们没有在图表中指定。 
如果您因这些事件而修改任何内容,点击事件不会被解雇。 这包括DOM树中更高的东西。 例如,这将防止在您的网站上使用jQuery进行单击操作:
 $(window).on('mousemove', function() { $('body').attr('rel', Math.random()); }); 
 编辑:澄清,jQuery的hover事件包括mouseenter和mouseleave 。 这些都将防止click如果内容改变。 
浏览器function检测库Modernizer包含对触摸事件的检查。
它的默认行为是将类应用于您的html元素,以检测每个要素。 然后,您可以使用这些类来设置文档的样式。
 如果没有启用触摸事件Modernizr可以添加一个no-touch的类: 
 <html class="no-touch"> 
然后用这个类来定义你的hover风格:
 .no-touch a:hover { /* hover styles here */ } 
您可以下载自定义的Modernizr版本,以根据需要添加尽可能less的特征检测。
以下是一些可能适用的类的示例:
 <html class="js no-touch postmessage history multiplebgs boxshadow opacity cssanimations csscolumns cssgradients csstransforms csstransitions fontface localstorage sessionstorage svg inlinesvg no-blobbuilder blob bloburls download formdata"> 
有些设备(如其他人所说的)既有触摸又有鼠标事件。 例如,Microsoft Surface有一个触摸屏,一个触控板和一个手写笔,当它hover在屏幕上方时,实际上会引起hover事件。
 任何禁用:hover基于“触摸”事件的:hover的解决scheme也将影响Surface用户(以及许多其他类似的设备)。 许多新的笔记本电脑是触摸,并会响应触摸事件 – 所以禁用hover是一个非常糟糕的做法。 
这是Safari中的一个错误,这种可怕的行为绝对没有理由。 我拒绝破坏非iOS浏览器,因为iOS Safari中存在一个显然已存在多年的错误。 我真的希望他们下周在iOS8上解决这个问题,但同时…
我的解决scheme
 有人build议使用Modernizr,Modernizr允许你创build自己的testing。 我基本上在这里做的是'抽象'的浏览器,支持的想法:hover到Modernizrtesting,我可以使用整个我的代码没有硬编码, if (iOS)整个if (iOS) 。 
  Modernizr.addTest('workinghover', function () { // Safari doesn't 'announce' to the world that it behaves badly with :hover // so we have to check the userAgent return navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? false : true; }); 
然后,CSS变成这样的东西
 html.workinghover .rollover:hover { // rollover css } 
只有在iOS上,此testing将失败并禁用翻转。
这种抽象的最好的部分是,如果我发现它在某个Android上打破了,或者如果它在iOS9中被修复的话,我可以修改testing。
将FastClick库添加到您的页面将导致移动设备上的所有点击事件(无论用户点击的位置)变成点击事件,因此它还应该修复移动设备上的hover问题。 我编辑你的小提琴作为一个例子: http : //jsfiddle.net/FvACN/8/ 。
只需在页面上包含fastclick.min.js库,然后通过以下命令激活:
 FastClick.attach(document.body); 
作为一个附带的好处,它也将消除令人讨厌的300毫秒onClick延迟移动设备遭受。
使用FastClick有一些小的后果,对于您的网站可能并不重要:
- 如果您点击页面上的某个位置,向上滚动,向下滚动,然后松开与最初放置的位置完全相同的位置,FastClick会将其解释为“点击”,即使显然不是。 至less这就是我目前使用的FastClick版本(1.0.0)的工作方式。 自该版本以来,有人可能已经解决了这个问题。
- FastClick删除了某人“双击”的能力。
基本上有三种情况:
-  用户只有一个鼠标/指针设备,可以激活:hover
-  用户只有一个触摸屏,并且不能激活:hover元素
- 用户同时拥有触摸屏和指针设备
如果只有前两种情况是可能的,用户具有指针或触摸屏,则最初接受的答案很好。 OP在4年前问这个问题时很普遍。 一些用户指出,Windows 8和Surface设备正在使第三种情况更有可能。
iOS解决scheme无法在触摸屏设备上进行hover(详见@Zenexer),但是会导致代码错误(如OP所述)。 仅对触摸屏设备禁用hover意味着您仍然需要编写触摸屏友好的替代scheme。 检测用户何时有指针和触摸屏进一步混浊的水域(如@Simon_Weaver解释)。
 在这一点上,最安全的解决scheme是避免使用:hover作为用户可以与您的网站互动的唯一方式。 hover效果是指示链接或button是否可操作的好方法,但不应要求用户hover元素才能在网站上执行操作。 
考虑到触摸屏的重新思考“hover”function有关替代用户体验方法的良好讨论。 答案中提供的解决scheme包括:
- 直接操作replacehover菜单(始终可见链接)
- 使用点击式菜单replacehover式菜单
- 将大量hover内容移到单独的页面中
 outlook未来,这可能是所有新项目的最佳解决scheme。 被接受的答案可能是第二好的解决scheme,但一定要考虑也有指针设备的设备。 小心不要消除function,当设备有触摸屏只是为了解决iOS的问题:hover黑客。 
一个更好的解决scheme,没有任何JS,CSS类和视口检查:您可以使用交互媒体function(媒体查询级别4)
喜欢这个:
 @media (hover) { // properties my:hover { color: red; } } 
iOS Safari 支持它
更多关于: https : //www.jonathanfielding.com/an-introduction-to-interaction-media-features/
.css中的JQuery版本使用.no-touch .my-element:hover所有hover规则包括JQuery和以下脚本
 function removeHoverState(){ $("body").removeClass("no-touch"); } 
然后在body标签中添加class =“no-touch”ontouchstart =“removeHoverState()”
一旦ontouchstart发动所有hover状态的class级被删除
当触摸不可用时,我只创build了hover效果,而不是创build了一个处理触摸事件的系统,并为我解决了这个问题。 首先,我定义了一个对象来testing“点击”(相当于“点击”)事件。
 touchTester = { touchStarted: false ,moveLimit: 5 ,moveCount: null ,isSupported: 'ontouchend' in document ,isTap: function(event) { if (!this.isSupported) { return true; } switch (event.originalEvent.type) { case 'touchstart': this.touchStarted = true; this.moveCount = 0; return false; case 'touchmove': this.moveCount++; this.touchStarted = (this.moveCount <= this.moveLimit); return false; case 'touchend': var isTap = this.touchStarted; this.touchStarted = false; return isTap; default: return true; } } }; 
然后,在我的事件处理程序中,我执行如下操作:
 $('#nav').on('click touchstart touchmove touchend', 'ul > li > a' ,function handleClick(event) { if (!touchTester.isTap(event)) { return true; } // touch was click or touch equivalent // nromal handling goes here. }); 
感谢@Morgan程序的答案,但是我稍微修改了JS函数获得“ touchstart ”(代码来自@Timothy Perez 答案 ),但是,你需要jQuery 1.7+
  $(document).on({ 'touchstart' : function(){ //do whatever you want here } }); 
鉴于Zenexer提供的响应,不需要额外HTML标记的模式是:
 jQuery('a').on('mouseover', function(event) { event.preventDefault(); // Show and hide your drop down nav or other elem }); jQuery('a').on('click', function(event) { if (jQuery(event.target).children('.dropdown').is(':visible') { // Hide your dropdown nav here to unstick } }); 
此方法首先触发鼠标hover,点击秒。
只要看看屏幕的大小….
 @media (min-width: 550px) { .menu ul li:hover > ul { display: block; } } 
下载你想要放入的代码
 // a function to parse the user agent string; useful for // detecting lots of browsers, not just the iPad. function checkUserAgent(vs) { var pattern = new RegExp(vs, 'i'); return !!pattern.test(navigator.userAgent); } if ( checkUserAgent('iPad') ) { // iPad specific stuff here }