返回

文章详情

工具提示需要延迟,然后需要跳过它

Hacker News2026年8月25日 16:35

在我产品 FrontPrep 的问题列表页面上,我在面试问题旁边显示公司徽标。当你将光标悬停在徽标上时,会显示一个工具提示,显示公司名称。有件事让我感到烦恼了好几天。 如果我只是将光标在页面上移动,工具提示会在沿途立刻显示出来。原因很简单:我将工具提示的延迟设置为 0,因此它在光标悬停在徽标上时立刻显示。为了解决这个问题,我添加了 200ms 的过渡延迟,这虽然有效但产生了新的问题。如果你查看用户界面,有几行多个徽标并排放置,因为在多家公司中提出了相同的面试问题。现在,从一个徽标移动到另一个徽标意味着每次悬停在不同的公司徽标上都要等待同样的 200ms 延迟,这感觉很迟钝,并导致了较差的用户体验。此帖子并不是关于构建工具提示。它是关于一个小的交互模式,与你在浏览器工具栏和各类网站中会找到的相同,而人们对此并不知情。这是我网站上体验前后变化的简短视频。它帮助你更好地理解问题。之前(没有 200ms 的延迟) 之后(有 200ms 的延迟和即时工具提示) 解决方案 我将把我的解决方案分为三个部分。你悬停在徽标上。工具提示在打开之前等待 200ms。 工具提示关闭,300ms 的计时器开始。我称之为温暖窗口或温暖页面。如果在这 300ms 计时器运行时你悬停在另一个徽标上,或者可以说当页面是温暖的,工具提示会立刻打开而无需等待或动画。当 300ms 计时器到期时,一切恢复正常,页面变得寒冷。如果你再次悬停在徽标上,下一个工具提示仍然需要等待 200ms。如果没有这一步,你打开的第一个工具提示将永久关闭整个页面的延迟。悬停 → 等待 200ms → 工具提示打开(页面现在变温暖)离开 → 工具提示关闭 → 300ms 冷却 ├─ 在冷却之前悬停另一个工具提示 → 立刻打开,页面保持温暖 └─ 冷却结束 → 页面变冷,200ms 的等待回来了 在 FrontPrep 中,我的工具提示是使用 Radix 和 Motion 构建的。我将展示一个更简单的 React 版本来演示这个模式,稍后在帖子中,我会将这个想法放入 Claude 技能中,你可以用来审核自己的代码库。以下是一个后续文章,复制了没有任何 JavaScript 的基本 UX。代码是如何工作的 我将尝试按光标移动时事情发生的顺序来解释代码。 第一步:你悬停在徽标上 当在徽标上触发 onMouseEnter 时,调用此函数:function handleEnter () { // `tooltips` 是一个 useContext 变量,其中跟踪组件之间的 isWarm 状态 如果 (tooltips.isWarm) { show(); return ; } // `openTimer` 是一个 useRef 变量,所以 .current 是你设置/访问值的方式。 openTimer.current = setTimeout(show, tooltips.openDelay); } 代码语言:JavaScript(javascript) 在悬停时,这个组件会问一个问题:页面是热的吗? 如果是,工具提示会立刻打开。 如果不是,它会启动一个 200ms 的计时器并等待。你可能想知道这个工具提示对象来自哪里。它来自于最后一步中我会讨论的 TooltipProvider。 第二步:工具提示打开 这是处理工具提示打开的 show 函数:function show () { setInstant(tooltips.isWarm); setOpen( true ); tooltips.markOpened(); } 代码语言:JavaScript(javascript) 这做了三件事:它将 tooltips.isWarm 的值复制到一个名为 instant 的状态中。 它打开了工具提示。 它告诉提供程序工具提示已打开,使页面变得温暖。 回到点 1,它复制了 tooltips.isWarm 返回的内容到一个名为 instant 的标志中,因为这个 instant 标志被添加到工具提示作为数据属性,CSS 用它来跳过进入动画。 .tooltip [data-instant= "true"] { transition-duration : 0ms ; } 代码语言:CSS(css) 这就是当页面变暖时,工具提示会在没有动画或延迟的情况下打开的原因。 第三步:你离开徽标 当在徽标上触发 onMouseLeave 时,调用此函数:function handleLeave () { clearTimeout(openTimer.current); 如果 (!open) return ; setOpen( false ); setInstant( false ); tooltips.markClosed(); } 代码语言:JavaScript(javascript) 首先,我们必须知道工具提示当前是否打开。 假设你的光标在 50ms 内穿过一个徽标,这远远少于 200ms,因此 handleEnter 启动的计时器仍在运行,而工具提示尚未打开。 handleLeave 中的 clearTimeout 会取消该计时器,因此工具提示根本不会打开,如果 (!open) return; 会立即停止函数,因为从未打开的工具提示没有任何内容可关闭,也没有冷却周期可以开始。在第一个视频中,一个扫视打开了路径中的每个工具提示;现在,同样的扫视不打开任何工具提示。如果工具提示打开,发生这种情况

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡