← ✦ UX 交互模式 · 那些有名字的交互细节 / Hover Intent:区分「路过」与「真的想看」 待审核 5 / 7
hover-intent · 悬停意图

Hover Intent:区分「路过」与「真的想看」

mouseenter 一触即发地展开菜单 / 预览,会在鼠标只是路过时频繁闪烁——用户的指针从屏幕一角移到另一角,沿途每个项都被点亮一次。Hover Intent 给「打开」加一道判定:指针进入后停留超过阈值才真正触发,离开则带一点关闭延迟(避免在项与浮层间穿行时误关)。下面两条菜单逻辑相同、只差这道判定。先快速从左划到右,再在某一项停住,看触发次数的差距。

本质是一个去抖 (debounce):把「进入」这个事件推迟 threshold 毫秒,若期间发生「离开」就取消。阈值是个权衡——太小 (<100ms) 形同没有,太大 (>400ms) 会让确有查看意图的用户感到迟滞。更精细的实现 (jQuery hoverIntent) 不看停留时长而看移动速度:采样两点间位移,降到某个速度以下才算「停下来了」,对快慢不一的手势更稳健。关闭延迟则解决另一个问题:浮层和触发区之间常有缝隙,延迟让指针得以「跨过」它。

enter 去抖 + leave 延迟关闭——两个 timer 而已:

el.addEventListener('mouseenter', () => {
  clearTimeout(closeTimer);
  openTimer = setTimeout(open, THRESHOLD);  // 停够久才开
});
el.addEventListener('mouseleave', () => {
  clearTimeout(openTimer);                  // 路过 → 取消打开
  if (isOpen) closeTimer = setTimeout(close, CLOSE_DELAY);
});

它和 Safe Triangle 互补:Hover Intent 管(区分路过与停留),Safe Triangle 管(区分穿堂而过与真的离开)。两者叠加,才有「不提前触发、也不中途消失」的多级菜单。