热门IT资讯网

处理粘性的4种新方法:在移动设备上悬停效果

发表于:2024-11-24 作者:热门IT资讯网编辑
编辑最后更新 2024年11月24日,CSS的古老之处:悬停伪类构成了许多CSS效果的支柱,当鼠标滚过页面上的元素时触发。在当今不断变化的环境中,触摸屏输入与鼠标共享中心舞台,这给网站管理员带来了一些难题。基于触摸的设备努力不被冷落,这种

CSS的古老之处:悬停伪类构成了许多CSS效果的支柱,当鼠标滚过页面上的元素时触发。在当今不断变化的环境中,触摸屏输入与鼠标共享中心舞台,这给网站管理员带来了一些难题。基于触摸的设备努力不被冷落,这种普遍的CSS功能确实可以响应悬停,但是对于它们来说唯一可行的方式是"点击"而不是实际的"悬停"。虽然这总体上是一件好事,但它会导致这些设备上所谓的"粘滞悬停"问题:hover样式与用户刚刚点击的元素保持一致,直到他/她再次点击文档中的其他位置,或者在某些情况下,在效果被取消之前重新加载页面。这种"永远在线"的悬停效果在某些情况下是良性的,但对其他人的用户体验是有害的甚至是有害的。例如,页面上的一组"volumn"按钮具有"悬停"效果,可以改变鼠标用户的背景颜色,当鼠标滑过按钮时,效果会通知用户按钮可以与之交互,但是触摸设备背景颜色"粘在"按钮上的按钮,它误导用户认为单击一下后音量不断增大或减小。

在本教程中,我们将介绍4种不同的方法来禁用或修改:hover移动设备上的默认效果,以便跨平台提供更好的用户体验。我们将从最保守的方法开始,然后再投入更加雄心勃勃的事情 ,同时考虑支持触摸屏和鼠标/触摸板输入和实时的混合设备。让我们滚动。

方法1-有条件地将" non-touch"CSS类添加到文档根元素

首先,一种保守的方法:hover,通过non-touch在设备被视为不支持时向根元素添加任意CSS类(即:" "),将CSS 样式限制为所谓的基于鼠标的设备(即:桌面)。触摸"。一个COM周一方法是使用JavaScript来作出这样的判断:

1

2

3

4

var touchsupport = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)

if (!touchsupport){ // browser doesn't support touch

document.documentElement.className += " non-touch"

}

non-touch现在只有在使用JavaScript测试触摸支持时返回false的设备的" "类,我们:hover才会修改相关样式以仅定位这些设备:

1

2

3

html.nontouch nav a:hover{ /* hover effect only visible to devices that report back as not supporting touch */

background: yellow;

}

这种方法简单而简洁,但并非没有缺陷。准确地检测触摸支持是非常困难的使用当前浏览器的API,并且将存在这样的情况:不支持触摸的浏览器(或反之亦然)将报告相反的情况。然而,总体而言,这种方法确实达到了"足够好"的门槛,其中:hover 效果不会影响用户体验 - 无论是横向还是负面 - 无论如何都要跨平台。

方法2-有条件地将" can-touch"CSS类添加到文档根元素

与第一种方法相反,这种方法可以让您:hover单独保留原始样式,而是:hover 针对触摸设备制作定制 样式。我们将利用JavaScript的" touchstart"事件,当用户与启用触摸的设备上的屏幕进行联系时调用该事件,首先实时确定设备确实支持触摸输入,然后再将" can-touch"类添加到文档根元素。

1

2

3

4

6

用户第一次触摸屏幕时,CSS类" can-touch"被添加到根元素,表示设备是基于触摸的。我们使用classList API- 它在移动浏览器上享有极好的支持 - 更优雅地将类添加到元素中。为了防止动作超出一次,我们立即从事件中取消注册已分配的功能。

通过此设置,我们可以:hover正常定义我们的初始样式,然后在触摸设备之后撤消或修改它,例如:

1

2

3

4

6

7

8

9

10

11

12

ul li a{

padding: 10px;

display: block;

}

ul li a:hover{

background: yellow;

}

html.can-touch ul li a:hover{

background: none; /* disable hover effect on touch devices */

}

这种方法可以说比分离触摸和非触摸设备的第一种更准确,尽管它确实需要用户在它开始之前先触摸屏幕。为了处理 :hover按需发生的效果,它可以工作,尽管取决于正常和"可以触摸"之间的样式差异:悬停类,页面布局的短暂转换可能会发生,因为后者应用于页面按需。此外,请注意,所有移动浏览器都不支持触摸事件,如" touchstart" ,IE和Firefox移动显然是其中两个。

方法3-使用CSS媒体查询级别4交互媒体功能

CSS Media Queries Level 4增加了对识别用户输入设备功能的支持。出于我们的目的,我们对" pointer"和" hover" 感兴趣,它告诉我们用户主要输入设备的精确程度以及它支持悬停的程度。查看以下CSS媒体查询以及它们有助于隔离的输入设备类型:

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

@media (pointer:coarse) {

/* Primary Input is a coarse pointer device such as touchscreen or XBox Kinect etc */

}

@media (pointer:fine) {

/* Primary Input is a fine pointer device such as a mouse or stylus */

}

@media (hover:none) {

/* Primary Input doesn't respond to hover at all, even partially (ie: there is no pointing device) */

}

@media (hover:on-demand) {

/* Primary Input responds to hover only via emulation, such as touch screen devices */

}

@media (hover:hover) {

/* Primary Input responds to hover fully, such as a mouse or a Nintendo Wii controller */

}

例如,您可以:hover 在媒体查询(@media hover:hover{})中定义常规样式,以将它们限制为:hover完全支持的设备(配备鼠标或某些指针设备的设备):

1

2

3

4

@media (hover:hover) {

nav a:hover{

background: yellow;

}

}

或离开你原来的更加渐进的方式 :hover风格不变,目标不支持设备的 :hover pletely:

1

2

3

4

@media (hover:none), (hover:on-demand) {

nav a:hover{ /* suppress hover effect on devices that don't support hover fully

background: none;

}

}

所有上述逻辑也可以使用JavaScript打包 ,例如:window.matchMedia()

1

var nofullhover = window.matchMedia("(hover:none), (hover:on-demand)").matches //returns true or false

虽然你可能认为你已经到达了检测:hover支持的圣杯 - 使用CSS Media Queries Level 4-但现实并未完全符合其潜力。首先是媒体查询4级交互媒体功能的不稳定浏览器支持。目前没有Firefox浏览器(最高为FF 50)支持它,这几乎使得这种方法在该领域的改进之前不切实际。其次,媒体查询4级交互媒体功能的当前规范在我看来对前两种处理方法提供的优势很小:hover跨平台的行为,除了它的优雅和没有JavaScript依赖。所有3种方法,无论它们在检测触摸还是无触摸支持方面都是准确的,都忽略了一种越来越受欢迎的设置,其中该设备同时支持触摸屏和鼠标/触控板。在这种情况下,上述检测方案中没有一个能够实时确定用户 当前正在使用哪个输入,而是仅在将设备报告为"触摸"时仅查看他们认为是设备的主要输入的内容。 "或"没有触摸/鼠标"。这意味着在大多数情况下,具有触摸和鼠标输入的笔记本电脑将始终作为触摸设备进行归类,有时根据具体设置,"鼠标"设备, :hover无论用户当前使用什么输入,相关的样式只能满足其中一个输入。这显然是一大短COM ING,一个通向下面我最后的检测方法。

方法4- can-touch根据当前用户输入类型动态添加或删除" "类

对于这最后的方法,我把它视为挑战 é了一种方法来确定用户是否使用了实时地触摸或鼠标/触控板基于输入。如上所述,到目前为止我们看到的所有先前检测方法在判断用户当前使用的输入类型时都是静态的; 当面对支持触摸和非触摸输入的混合设备以及用户可以随时在这些输入之间切换的事实时,就像他们所说的那样,"休斯顿我们遇到了问题"。目前所有可用的浏览器API只能告诉我们用户设备支持的输入类型而不是他/她目前正在使用的输入类型,现在是时候进行一些越野编码以试图规避这种限制。

实时检查用户输入类型背后的基本思想很简单,魔鬼就是细节。我们已经拥有上面方法2中的一半神奇公式,我们转向JavaScript的" ontouchstart"事件处理程序,以便在用户与屏幕进行联系时通知(因此当时正在使用触摸)。但是当用户切换到鼠标/触控板时呢?第一个想法自然就是参加JavaScript的鼠标相关事件之一 - " mouseover"," mousemove"," mouseenter"等 - 以帮助我们拨打电话,但是一旦你意识到触摸屏设备也响应鼠标事件,那么兴奋是短暂的(很像CSS:hover每当用户点击屏幕时,就会侵蚀触摸设备上所有这些事件之间的区别。

因此,显然试图告诉鼠标事件是由实际鼠标/触控板触摸何时触摸触摸屏上的触摸要比看到它更难,尽管一切都没有丢失。我发现当在页面上注册了" touchstart"和鼠标事件(如" mouseover")时,当用户触摸屏幕时触发的两个事件的顺序始终是前者,后面是后一个事件:

1

2

document.addEventListener('touchstart', functionref, false) // on user tap, "touchstart" fires first

document.addEventListener('mouseover', functionref, false) // followed by mouse event, ie: "mouseover"

我们可以利用这个可预测的事件序列来区分文档上的实际触摸与实际鼠标悬停(即:在混合设备上),通过在发射时暂时阻止第一个事件阻止第二个事件来指示这是触摸事件,过滤掉真正的鼠标悬停事件。让我们来看看这一切是如何COM上课共同创造的代码,动态添加或删除" can-touch"类文档根目录,以反映此时的用户的当前输入类型:

1

2

3

4

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

三十


尝试一下现场演示以上在桌面上,触摸设备和混合设备,看的CSS如何:hover影响是每当触摸用于与链接交互,但活跃起来,如果鼠标或触控板来代替上课处于休眠状态。让我们分解它的工作原理:

  • 我们在文档上注册两个事件" touchstart"和" mouseover",以便在用户与页面交互时捕获两种类型的事件。

  • 在非触摸设备(如桌面)上,只会mouseover触发" "事件。removetouchclass() 虽然什么都不做,但调用该函数,因为isTouchcurRootClass变量将始终分别为false""(空字符串)。换句话说,没有" can-touch"类被添加到文档中。

  • 在触摸设备(包括用户当前正在使用"触摸"时的混合设备)上,触摸时触发" touchstart"和" mouseover"事件,前者随后触发。

  • 每当用户触摸屏幕时,调用函数 addtouchclass()isTouch 变量设置true为在将" can-touch"CSS类添加到面向根之前将当前输入类型指示为触摸。为了防止removetouchclass() 在同一个触摸操作期间调用函数并撤消刚刚完成的操作,我们添加以下行以 addtouchclass()isTouch变量的状态保持为真500毫秒:

    isTouchTimer = setTimeout(function(){isTouch = false}, 500)

    使用上面的关键代码行,当removetouchclass() 也尝试紧跟在" touchstart"之后运行(因为触摸设备也响应鼠标事件),它被阻止,因为此时的值isTouch仍然为真。不久之后,isTouch变量将自身重置为false在每次触摸动作之后再次确保在使用触摸输入后isTouch不会永久停留在该 true状态,并且如果用户之后切换到它(例如在混合设备上),则可以继续对可能的鼠标/触控板输入作出反应,然后打电话removetouchclass()

所有这些最终导致can-touch在文档中实时添加或删除" "类以反映用户当前正在使用的输入设备。从我的测试,似乎整个每台设备我把它那可预见的工作支持JavaScript触摸事件,但留下一个 COM下面包换,如果你发现,否则。

结论

在本教程中,我们研究了4种不同的方法来解决:hover移动设备上的棘手问题,从不同的角度进行,以检测用户的输入设备何时触摸与非触摸。直到触摸设备支持实际悬停(可能使用相机检测手指何时在元素上徘徊),它们允许我们在 不同平台上创建更好的体验,具有不同程度的准确性和易于实现。在许多情况下,它比什么都不做要好。


0