使用安全三角和延迟取消的方法优化 hover 浮层

23,683次阅读
没有评论

共计 2282 个字符,预计需要花费 6 分钟才能阅读完成。

碰到一个算是比较常见问题,如下图:

使用安全三角和延迟取消的方法优化 hover 浮层

需求:显而易见,当 hover 在对话框上时,显示反馈浮层,使用 hover 或鼠标事件都能实现。
BUG:由于浮层跟主体之间有空隙,当鼠标移动向浮层时触发了 MouseLeave 事件,以至于鼠标没来及移动到浮层上,浮层就消失掉了。

以下是两种解决思路:

方案一:延迟取消

这是个比较简单的方案,可快速实现:当鼠标离开主体时使用 debounce 延迟触发 onMouseLeave 函数,在此期间如果鼠标移动进浮层,则再取消 onMouseLeave。

以 react 为例,伪代码如下:

完成后效果如下:

使用安全三角和延迟取消的方法优化 hover 浮层

简单完美优雅,但略显无趣,我们看看另一种解决方案。

方案二:安全三角

这是一个在 Menu 组件上常见到的方案,主要思路是 增加一个不可见的安全元素,填平浮层和主体间的空隙,保证鼠标在两者间移动时不发生其他事件(例如误触发 MouseLeave 或者误触发其他菜单项的 MouseEnter)。

在 Menu 组件中的示意图如下:

使用安全三角和延迟取消的方法优化 hover 浮层

图里这个绿色的三角可以使用 SVG 创建,注意以下两点:

  1. Menu 这里使用三角形是必要的,因为若使用矩形,区域太大,会影响用户选择其他菜单项。
  2. SVG 仅由 path 元素构成,中间是空的,所以需要使用 pointer-event: auto 来保证这块三角区域不会发生事件穿透(避免在 path 内部发生 onMouseLeave 事件)。

另外,本文开头的对话框需求的浮层问题直接使用矩形作为安全元素 就可以解决,不用三角形就也不用使用 SVG,直接一个空 div 即可,但 字数太少 难度太低,所以我们以 Menu 为例实现这个三角吧,伪代码如下:

脑海里想象一个矩形,它的左下角是坐标起点 0,0,宽度为 svgWidth,高度为 svgHeightpath 绘制的三角形在其中间,如图:

使用安全三角和延迟取消的方法优化 hover 浮层

  • 这里 0,0 是矩形的起点,可以通过选中菜单项(鼠标)的位置和其子菜单项的高确定。
  • 0, ${mouseY-submenuY} 是三角形路径的起点,也就是鼠标所在菜单项的中央位置。
  • 接着画两条线:L ${svgWidth},${svgHeight} 和 L ${svgWidth},0。第一条线(line, L)链接向矩形右上角的坐标,第二条线链接向矩形右下角的坐标。
  • z 表示闭合整个路径,这样就形成了三角形,大功告成。

如此一来,把这个三角形作为 SafeArea 组件放进菜单项就行:

这样就构建完成了一个用户交互十分友好的安全三角区域,既不会影响用户选择其他菜单项,又能保证用户在鼠标斜着滑向子菜单时不会出现意外。

关于更多安全三角的内容,可以参考该文章:
https://www.smashingmagazine.com/2023/08/better-context-menus-safe-triangles/

文章来源: 使用安全三角和延迟取消的方法优化 hover 浮层

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于1970-01-01发表,共计2282字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)