处理粘性的4种新方法:在移动设备上悬停效果
CSS的古老之处:悬停伪类构成了许多CSS效果的支柱,当鼠标滚过页面上的元素时触发。在当今不断变化的环境中,触摸屏输入与鼠标共享中心舞台,这给网站管理员带来了一些难题。基于触摸的设备努力不被冷落,这种普遍的CSS功能会对悬停做出响应,但是对于它们来说,唯一的方法就是“点击”而不是实际的“悬停”。虽然这总体上是一件好事,但它会导致这些设备上所谓的“粘滞悬停”问题 :hover 样式与用户刚刚点击的元素保持一致,直到他/她再次点击文档中的其他位置,或者在某些情况下,在效果被取消之前重新加载页面。这种“永远在线”的悬停效果在某些情况下是良性的,但对其他人的用户体验来说是一种麻烦甚至是有害的。例如,页面上的一组“volumn”按钮具有“悬停”效果,可以改变鼠标用户的背景颜色,当鼠标滑过按钮时,效果会通知用户按钮可以与之交互,但是触摸设备背景颜色“粘在”按钮上的按钮,它误导用户认为单击一下后音量不断增大或减小。
在本教程中,我们将介绍4种不同的方法来禁用或修改 :hover 移动设备上的默认效果,以便跨平台提供更好的用户体验。我们将从最保守的方法开始,然后再投入 事情 ,同时考虑到支持触摸屏和鼠标/触摸板输入和实时的混合设备。让我们滚动。
方法1-有条件地将“ non-touch ”CSS类添加到文档根元素
首先,一种保守的方法 :hover ,通过 non-touch 在设备被视为不支持时向根<html>元素添加任意CSS类(即:“ ”),将CSS 样式限制为所谓的基于鼠标的设备(即:桌面)。触摸”。一种常见的方法是使用JavaScript来做出这样的决定:
non-touch 现在只有在使用JavaScript测试触摸支持时返回false的设备上才有“ ”类,我们会修改 :hover 相关样式以仅定位这些设备:
这种方法简单而简洁,但并非没有缺陷。准确地检测触摸支持是非常困难的使用当前浏览器的API,并且将存在不支持触摸(或反之亦然)的浏览器将报告相反的情况。但总的来说,这种方法确实达到了“足够好”的门槛,其中 :hover 效果不会影响用户体验 - 无论是横向还是负面 - 无论如何都要跨平台。
方法2-有条件地将“ can-touch ”CSS类添加到文档根元素
与第一种方法相反,这种方法可以让您 :hover 单独保留原始样式,而是制作 :hover 针对触摸设备的自定义 样式。我们将利用JavaScript的“ touchstart ”事件,每当用户与启用触摸的设备上的屏幕进行联系时调用该事件,首先实时确定设备确实支持触摸输入,然后再将“ can-touch ”类添加到文档根元素。
用户第一次触摸屏幕时,CSS类“ can-touch ”被添加到根元素,表示设备是基于触摸的。我们使用 classList API - 它在移动浏览器上享有极好的支持 - 更优雅地将类添加到元素中。为了防止操作超出一次,我们立即从事件中取消注册已分配的功能。
通过此设置,我们可以 :hover 正常定义初始样式,然后在触摸设备之后撤消或修改它,例如:
这种方法可以说比分离触摸和非触摸设备的第一种方法更准确,尽管它确实需要用户在它开始之前先触摸屏幕。为了处理 :hover 按需发生的效果,它可以工作,尽管取决于正常和“可以触摸”之间的样式差异:悬停类,页面布局的短暂转换可能会发生,因为后者应用于页面按需。此外,请注意, 所有移动浏览器都不支持 触摸事件,如“ touchstart ” ,IE和Firefox移动显然是其中两个。
方法3-使用CSS媒体查询级别4交互媒体功能
CSS Media Queries Level 4增加了对识别用户 输入设备功能的支持 。出于我们的目的,我们对“ pointer ”和“ hover ” 感兴趣,它告诉我们用户主要输入设备的精确程度以及它支持悬停的程度。查看以下CSS媒体查询以及它们有助于隔离的输入设备类型:
例如,您可以 :hover 在媒体查询( @media hover:hover{} )中定义常规样式,以将它们限制为 :hover 完全支持的设备(配备鼠标或某些指点设备的设备):
或者为了使原始 :hover 样式不受影响的更先进的方法 ,目标设备不完全支持 :hover :
所有上述逻辑也可以使用JavaScript打包 ,例如: window.matchMedia()
虽然你可能认为你已经到达了检测 :hover 支持的圣杯 - 使用CSS Media Queries Level 4- 但现实还没有完全符合它的潜力 。首先是媒体查询4级交互媒体功能的 不稳定浏览器支持 。目前没有Firefox浏览器(最高为FF 50)支持它,这几乎使得这种方法在该领域的改进之前不切实际。其次,媒体查询4级交互媒体功能的当前规范在我看来对前两种处理方法提供了一些优势 :hover 跨平台的行为,除了它的优雅和没有JavaScript依赖。所有3种方法,无论它们在检测触摸还是无触摸支持方面都是准确的,都忽略了一种越来越流行的设置,即设备同时支持触摸屏和鼠标/触控板。在这种情况下,上述检测方案都不能确定用户 当前正在 使用哪个输入,而是仅仅在将设备报告为“触摸”时仅查看他们认为是设备的主要输入的内容。 “或”没有触摸/鼠标“。这意味着在大多数情况下,具有触摸和鼠标输入的笔记本电脑将始终作为触摸设备进行归类,有时根据具体设置,“鼠标”设备, :hover 无论用户当前使用什么输入,相关的样式只能满足其中一个输入。这显然是一个主要的缺点,导致我的最终检测方法如下。
方法4- can-touch 根据 当前 用户输入类型动态添加或删除“ ”类
对于这个最终方法,我接受了一个挑战,想出一种方法来确定用户是否实时使用触摸或鼠标/触控板输入。如上所述,到目前为止我们看到的所有先前检测方法在判断用户当前使用的输入类型时都是静态的; 当遇到支持触摸和非触摸输入的混合设备以及用户可以随时在这些输入之间切换的事实时,就像他们所说的那样,“休斯顿我们遇到了问题”。目前所有可用的浏览器API只能告诉我们用户设备支持的输入类型,而不是他/她目前正在使用的输入类型,现在是时候进行一些越野编码以试图规避这种限制。
实时检查用户输入类型背后的基本思想很简单,魔鬼就在细节中。我们已经拥有上面方法2中的一半神奇公式,我们转向JavaScript的“ ontouchstart ”事件处理程序,以便在用户与屏幕进行联系时获得通知(因此当时正在使用触摸)。但是当用户切换到鼠标/触控板时呢?第一个想法当然是招募JavaScript的鼠标相关事件之一 - “ mouseover ”,“ mousemove ”,“ mouseenter ”等 - 以帮助我们拨打电话,但是一旦你意识到触摸屏设备也响应鼠标事件,那么兴奋是短暂的(很像CSS :hover 每当用户点击屏幕时,就会侵蚀触摸设备上所有这些事件之间的区别。
因此,显然试图告诉鼠标事件是由实际的鼠标/触控板触摸何时触摸触摸屏上的触摸要比眼睛更难,尽管一切都没有丢失。我发现当在页面上注册“ touchstart ”和鼠标事件(如“ mouseover ”)时,当用户触摸屏幕时触发的两个事件的顺序始终是前者,后面是后一个事件:
我们可以利用这种可预测的事件序列来区分文档上的实际触摸与实际鼠标悬停(即:在混合设备上),通过使第一个事件一旦被触发暂时阻止第二个事件来指示这是触摸事件并且过滤掉真正的鼠标悬停事件。让我们看看这一切是如何组合起来创建代码,动态地 can-touch 向文档根添加或删除“ ”类以反映此时用户的当前输入类型:
扫一扫,关注我们