当前位置: 首页 > Web前端 > JavaScript

浅谈 -hover 伪类选择器在 touch 环境如何禁止生效的问题

时间:2023-03-27 01:36:36 JavaScript

讨论:hover伪类选择器如何在触摸环境样式中禁止生效,但是在触摸屏操作环境下表现却不太理想,主要是触摸屏操作没有所谓的悬停状态像鼠标一样,所以点击后才生效,又不像鼠标去掉这个概念,所以直到元素失焦才会失效,这就造成了有时候样式不符合预期效果的情况,所以有人会希望selector在触摸屏操作的时候不生效,但是这篇文章我们就来探讨一下如何实现。01.使用@mediamediaquery从MediaQueriesLevel4开始,浏览器增加了hover查询条件,用于检测当前环境的“主要”输入设备是否支持:hover选择器,有两个值hover和none的,前者符合,后者不符合,所以用@media(hover:hover){}实现支持:hover选择器的判断,用@media(hover:none){}实现表示不支持:hover选择器的判断,下面是一个关于查询条件的简单案例。<样式>#button01:hover{background-color:#f00;color:#fff;}@media(hover:hover){#button02:hover{background-color:#f00;color:#fff;}}}style>button01button02↓查看&代码↑以上截图在Windows7Chrome作为中操作的结果,我们为两个按钮设置了:hover样式。当样式生效时,背景会变成红色,文字会变成白色,但是第二个按钮生效的条件是主输入设备支持:hover选择器。OK,在PC模式下,由于我们使用的是鼠标,悬停时两个按钮的样式都会生效,但是接下来我们切换到移动模拟状态,此时主要输入设备变为触摸屏,所以第二个按钮正在使用点击后,:hover样式不会生效。这是完美的?事实上,情况并非如此。首先,这个媒体查询条件在一些低版本的浏览器中是不支持的。比如IE11不支持,存在一些兼容性问题。第二,一些同时支持鼠标和触摸屏的设备,比如Surface,被判断为“主”输入设备有问题。他们默认的主要输入设备是触摸屏,但是插入鼠标后这个判断不会自动改变,所以这个查询条件是行不通的。可以参考patrickhlauke.github。io了解有关查询异常的更多信息。02、使用JavaScript监听和使用媒体查询的方法虽然简单,但是存在一些兼容性问题。虽然随着浏览器的升级,以后的兼容性肯定会提高,但目前确实无计可施。如果你想要更好的兼容性一些,也许你可以尝试使用JS。最简单的方法是绑定mousemove事件和touchstart事件。当判断触发touchstart后500毫秒触发了mousemove,则认为是在使用鼠标,否则就是在使用下面是一个简单的例子。button01;button02↓查看&代码↑以上截图是在Windows7的Chrome中运行的结果。我们已经为两个按钮设置了:hover样式。当样式生效时,背景会变成红色,文字会变成白色,但是第二个按钮的样式生效的条件是存在isMouse类名,即只有它才会生效有老鼠的时候。在PC模式下,使用的是鼠标,所以两个按钮在悬停时样式会生效,不过这时候我们切换到移动端模拟状态。此时JS判断没有鼠标,所以点击第二个按钮后,:hover样式不会生效。这样可以吗?并不真地!这个判断有个问题,就是当目标节点被按下时,如果按下时间超过500毫秒,就会被误判为鼠标设备,触摸屏设备在按下时往往会变成一个圆圈长按Text或弹出菜单,此时操作可能出错。在上面的截图中,终于出现了长按导致#button02响应错误的情况,那么如何解决呢?这涉及到不同浏览器的交互细节,确实很难处理。建议直接使用现成的插件。03.使用xj.operate解决方案XJ写了一个xj.operate插件来解决本文关注的问题。它具有以下三个特点。首先,它的目的是区分当前操作的是鼠标还是触摸屏。它不仅仅是用来判断是否支持:hover,所以适用范围更广。其次,它解决了长按会导致误判的问题,但是你也可以让长按触发:hover成为一种Features,最后它提供了一些方法让我们可以临时转换状态,以实现一些特殊的需求.button01button02↓查看&代码↑以上代码与第2章代码相同,只是JS改成了插件的CDN,并且类名由isMouse改为xj-operate-mouse,在截图中我们可以看到即使在触屏环境下按住#button02也不会出现错误响应。如果你觉得xj-operate-mouse类名太长,还是想用一个更短的isMouse或者其他自定义类名,也可以通过配置实现插件化。关于插件的更多细节可以查看插件文档,这里不再赘述。其实业界还有其他解决hoverquery兼容性的方案,比如大家熟知的mq4-hover-shim,但是根据XJ的实测,发现这个方案用处不大。它使用window.matchMedia()来判断浏览器是否支持悬停查询,但是我们在上面第一章说过,有些设备在查询的时候会出错,所以window.matchMedia()的判断可能是错误的,所以意义不大。相比之下,xj.operate可能更可靠。参考内容ZhangXinxu-CSSany-hoverany-pointermediaqueryandinteractiveexperienceimprovementPatrickH.Lauke-Interactivemediafeaturesandtheirpotential(forincorrectassumptions)Microsoft-@media'shoverqueryisinvalidinWin11'sSurfacebugs。chromium-@media的悬停查询在Win10设备上不起作用@mediahoverMDN-@mediaany-hoverMDN-@mediapointerMDN-@mediaany-pointerMDN-指针事件MDN-PointerEventpatrickhlauke-不同浏览器中@media媒体查询的悬停/指针条件patrickhlauke-测试Touch相关事件和Pointer相关事件在不同环境和不同浏览器下的结果玄魂-(翻译)PointerEventApithatintegratemouse,touchandstyluseventsACGTOFE-把鼠标,触摸屏,触控笔统一起来,PointerEvents引入xiaoc_-Surface笔记本上的手势事件xiaoc_-Surface笔记本上的手势事件XJ.Chen-xj.operate