FEATURED · 精选文章

前端Tooltip延迟显示与跳过逻辑:从原理到React/Vue实现

发布时间 / 2026/8/29 16:40:44
来源 / 创域科博编辑部
栏目 / 资讯中心
前端Tooltip延迟显示与跳过逻辑:从原理到React/Vue实现 做前端交互时工具提示Tooltip是一个看起来很基础、但细节很多的组件。之前接了一个后台管理系统的需求表格列名要加 Tooltip交互要求是鼠标悬停 300ms 后才显示鼠标移开后如果提示还没到展示时间就不要再弹出来如果鼠标已经移动到浮层内部则浮层不能关闭。初次实现时我以为加一个 CSStransition-delay就能搞定结果在边界场景里踩了不少坑。这篇文章会围绕“工具提示需要延迟然后需要跳过它”这个交互目标完整梳理实现思路。无论你是刚接触前端的同学还是在业务中已经写了很久 Tooltip 的开发者都能从里面找到可复用的代码和排查方法。1. 工具提示的延迟交互它是什么为什么重要1.1 工具提示到底是什么工具提示也就是 Tooltip是在用户将鼠标悬停在某个元素上时出现的短暂说明性浮层。它通常包含一段文字、一个快捷键提示或者一段简短的说明。举几个常见场景表格列名太长悬停时显示完整标题。按钮只显示图标悬停时说明按钮功能。图表中某个数据点悬停时展示具体数值。导航菜单项悬停时展示子菜单名称。工具提示的设计目标是“在需要时提供信息在不需要时让开”所以它的显示和隐藏时机非常重要。如果一悬停就立刻弹出页面会显得很“躁”如果延迟太长用户又会觉得系统没反应。1.2 延迟显示的两个核心作用为什么要给工具提示加延迟我认为主要有两个原因。第一降低误触发概率。用户鼠标从屏幕右上角滑向左下角时会经过很多元素。如果每个元素都立刻弹出提示页面会连续闪现一堆浮层干扰视线。加一个 200ms 到 500ms 的延迟可以确保用户“真正停留在某个元素上”时才展示提示。第二让视觉过渡更平滑。工具提示从出现到消失如果配合透明度过渡transition观感会更自然。延迟只是控制“什么时候开始展示”透明度控制“展示的过程是怎样的”两者结合才是完整的交互。1.3 “需要延迟然后需要跳过它”怎么理解项目标题里的这句“需要延迟然后需要跳过它”实际上包含了两个阶段需要延迟鼠标进入触发区域后不要立刻显示提示而是等一小段时间。如果在这段时间内鼠标移出了触发区域那么延迟计时取消提示不再显示。跳过它某些场景下延迟过程需要被中断或跳过。比如用户已经看过一次提示再次悬停时不需要重复展示或者鼠标快速划过多个元素时前一个元素还没到展示时间就已经离开了那就不必再弹出来。所以“延迟”和“跳过”不是矛盾关系而是同一个交互流程里的两个分支时间到了就显示时间没到人就走了就不显示。2. 环境准备与示例项目结构2.1 运行环境说明本文的示例以浏览器端为主不涉及复杂构建工具。操作系统Windows / macOS / Linux 均可。浏览器Chrome、Edge、Firefox 等现代浏览器。开发工具VS Code 或任意文本编辑器。前端基础HTML、CSS、JavaScriptReact 示例需要 Node.js 环境Vue 示例需要 Vue 3。版本不需要完全固定示例代码使用的是通用 API。如果你的项目里 React 或 Vue 版本较旧请按对应版本调整写法。2.2 示例项目结构为了对照阅读我建议你建一个如下结构的目录tooltip-delay-demo/ ├── index.html # 原生 JavaScript 示例 ├── style.css # 样式文件 ├── script.js # 原生 JS 交互逻辑 ├── react-demo/ # React Hook 示例 │ ├── App.jsx │ ├── useTooltip.js │ └── Tooltip.jsx ├── vue-demo/ # Vue 指令示例 │ ├── App.vue │ └── directive.js └── README.md # 说明文档本文不会把每个文件完整拷贝而是按方案拆分给出核心代码片段方便你直接放到对应文件中。2.3 基础 HTML 模板先准备一个最基础的 HTML 页面后面所有方案都围绕它展开。!DOCTYPE html html langzh-CN head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / titleTooltip 延迟示例/title link relstylesheet hrefstyle.css / /head body div classcontainer button classtarget>.tooltip { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.2s ease, visibility 0s linear 0.2s; } .target:hover .tooltip { opacity: 1; visibility: visible; transition-delay: 0.3s, 0s; }这里有两个细节需要注意visibility是离散属性不能渐变。所以只对opacity做过渡但visibility也要配合切换否则透明元素会遮挡点击事件。visibility的过渡时间需要设为0s并且设置一个等于透明度过渡时间的延迟这样隐藏时透明度先渐变结束后才真正不可见。pointer-events: none是为了避免不可见的浮层拦截鼠标事件。3.2 延迟隐藏的实现上面代码中visibility的transition-delay: 0.2s已经实现了“延迟隐藏”的效果鼠标移开后透明度先过渡 0.2s然后浮层才完全不可见。如果你想实现更长的隐藏延迟比如鼠标移出后浮层还停留 300ms 再淡出可以这样调整.tooltip { opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.2s ease, visibility 0s linear 0.5s; } .target:hover .tooltip { opacity: 1; visibility: visible; transition-delay: 0.3s, 0s; }这里的含义是悬停时透明度延迟 300ms 后开始过渡到 1同时visibility立刻变为 visible。移开时透明度立即开始过渡同时visibility延迟 500ms 后再变成 hidden。3.3 CSS 方案的局限纯 CSS 方案虽然代码最少但有明显的局限无法精确中断。如果用户在延迟期间移出CSS 的延迟不会“取消显示”只是延迟结束后触发过渡。在某些浏览器里快速划过时依然可能出现短暂闪烁。交互边界不好处理。如果 tooltip 浮层本身是触发元素的一部分比如浮层内部有链接可以点击纯 CSS 很难区分“鼠标在触发元素上”还是“鼠标在浮层上”。位置控制不灵活。CSS 方案只能控制简单的相邻元素关系真实项目中 Tooltip 的位置通常需要根据视口边界动态计算。“跳过”逻辑无法表达。比如“用户看过后不再重复显示”这种业务规则CSS 是做不到的。所以CSS 方案只适合非常简单的页面真正业务开发我更推荐使用 JavaScript 方案。4. JavaScript 方案setTimeout 与 clearTimeout4.1 核心思路JavaScript 方案的核心是利用setTimeout做延迟利用clearTimeout做取消。整个流程是鼠标进入触发元素时启动一个延迟计时器。延迟时间内鼠标没有离开则计时器到点后显示 Tooltip。延迟时间内鼠标离开了则clearTimeout取消计时器Tooltip 不显示。鼠标离开已经显示的 Tooltip 时立即或延迟隐藏。这套逻辑天然支持“延迟期间跳过显示”的需求因为取消计时器本身就是一种跳过。4.2 基础实现先写一个完整的原生 JavaScript 版本。HTML 结构可以继续使用第 2 节的模板CSS 只负责视觉样式不负责显隐控制。// 文件路径script.js const target document.querySelector(.target); const tooltip document.getElementById(tooltip); let showTimer null; let hideTimer null; const SHOW_DELAY 300; // 显示延迟 300ms const HIDE_DELAY 150; // 隐藏延迟 150ms // 显示 Tooltip function showTooltip() { tooltip.classList.add(visible); tooltip.textContent target.dataset.tip; positionTooltip(); } // 隐藏 Tooltip function hideTooltip() { tooltip.classList.remove(visible); } // 计算并设置 Tooltip 位置 function positionTooltip() { const rect target.getBoundingClientRect(); const tooltipRect tooltip.getBoundingClientRect(); const top rect.top - tooltipRect.height - 8; const left rect.left rect.width / 2 - tooltipRect.width / 2; tooltip.style.top ${top window.scrollY}px; tooltip.style.left ${left window.scrollX}px; } // 鼠标进入触发元素 function handleMouseEnter() { clearTimeout(hideTimer); showTimer setTimeout(() { showTooltip(); }, SHOW_DELAY); } // 鼠标离开触发元素 function handleMouseLeave() { clearTimeout(showTimer); hideTimer setTimeout(() { hideTooltip(); }, HIDE_DELAY); } target.addEventListener(mouseenter, handleMouseEnter); target.addEventListener(mouseleave, handleMouseLeave);对应 CSS.tooltip { position: absolute; padding: 6px 10px; background: #333; color: #fff; border-radius: 4px; font-size: 14px; opacity: 0; visibility: hidden; transition: opacity 0.2s ease, visibility 0.2s ease; pointer-events: none; white-space: nowrap; z-index: 1000; } .tooltip.visible { opacity: 1; visibility: visible; }positionTooltip函数用getBoundingClientRect获取触发元素的位置然后让 Tooltip 显示在触发元素上方居中位置。这里加上window.scrollY是因为getBoundingClientRect返回的是视口坐标而绝对定位需要相对文档的坐标。运行这段代码时你会看到鼠标悬停按钮后约 300ms 才出现 Tooltip。鼠标移开后Tooltip 延迟 150ms 再淡出。4.3 跳过逻辑延迟期间鼠标移开这个场景其实已经在基础实现里实现了。当鼠标在 300ms 内离开触发元素handleMouseLeave会执行clearTimeout(showTimer)所以 Tooltip 永远不会显示。我们不妨把“跳过”拆成两个更明确的场景场景一鼠标在延迟期间移出触发元素mouseenter 触发 - 启动 showTimer mouseleave 触发 - clearTimeout(showTimer) 结果Tooltip 不显示这就是最典型的“然后需要跳过它”。场景二鼠标快速划过多个连续元素如果页面上有多个按钮每个按钮都需要 Tooltip你可能会想到给每个元素都绑定事件。但快速从第一个按钮滑到第二个按钮时第一个按钮的延迟计时器可能没有及时清除导致 Tooltip 在第二个按钮已经悬停时才冒出来。解决方法是当鼠标进入新元素时先清除之前所有的计时器再启动新的计时器。let showTimer null; let hideTimer null; document.querySelectorAll([data-tip]).forEach((el) { el.addEventListener(mouseenter, function () { clearTimeout(showTimer); clearTimeout(hideTimer); showTimer setTimeout(() { showTooltipFor(el); }, 300); }); el.addEventListener(mouseleave, function () { clearTimeout(showTimer); clearTimeout(hideTimer); hideTimer setTimeout(() { hideTooltip(); }, 150); }); });注意这里把target从全局变量改成了事件函数中的elshowTooltipFor负责动态读取当前触发元素的>tooltip.addEventListener(mouseenter, function () { clearTimeout(hideTimer); }); tooltip.addEventListener(mouseleave, function () { hideTimer setTimeout(() { hideTooltip(); }, HIDE_DELAY); });这样实现后鼠标从按钮移到 Tooltip 上时隐藏计时器被清掉Tooltip 不会消失。当鼠标移出 Tooltip 一定距离后才会延迟关闭。如果你的 Tooltip 是插入到触发元素内部的那么鼠标进入 Tooltip 时会同时触发父元素的mouseenter不需要额外处理。但如果 Tooltip 是独立的兄弟节点或body下的节点就必须处理这个边界。5. React 方案自定义 Hook 封装5.1 需求分析在 React 项目中最合适的做法是把延迟逻辑封装成自定义 Hook然后在组件里复用。这样业务代码可以非常简洁。我们要实现的能力传入显示延迟参数、隐藏延迟参数。返回 Tooltip 可见状态和事件绑定对象。支持鼠标从触发元素移到 Tooltip 浮层上时不关闭。在组件卸载时清理计时器。5.2 useTooltip Hook 实现// 文件路径react-demo/useTooltip.js import { useCallback, useEffect, useRef, useState } from react; export default function useTooltip({ showDelay 300, hideDelay 150, } {}) { const [visible, setVisible] useState(false); const showTimerRef useRef(null); const hideTimerRef useRef(null); const clearTimers useCallback(() { if (showTimerRef.current) { clearTimeout(showTimerRef.current); showTimerRef.current null; } if (hideTimerRef.current) { clearTimeout(hideTimerRef.current); hideTimerRef.current null; } }, []); const showTooltip useCallback(() { clearTimeout(hideTimerRef.current); showTimerRef.current setTimeout(() { setVisible(true); }, showDelay); }, [showDelay]); const hideTooltip useCallback(() { clearTimeout(showTimerRef.current); hideTimerRef.current setTimeout(() { setVisible(false); }, hideDelay); }, [hideDelay]); useEffect(() { return () clearTimers(); }, [clearTimers]); return { visible, showTooltip, hideTooltip, clearTimers, }; }代码说明showTooltip会先清除隐藏计时器再启动显示计时器。这可以处理“鼠标离开后又很快回来”的场景避免显示、隐藏计时器互相打架。hideTooltip会先清除显示计时器再启动隐藏计时器。这样鼠标在延迟显示期间离开延迟显示被取消。useEffect返回的清理函数会在组件卸载时调用避免组件已卸载但计时器还在执行setVisible导致内存泄漏。5.3 组件集成与参数说明有了 Hook写 Tooltip 组件就很干净了。// 文件路径react-demo/Tooltip.jsx import { useRef } from react; import useTooltip from ./useTooltip; export default function Tooltip({ trigger, tip, showDelay, hideDelay }) { const { visible, showTooltip, hideTooltip } useTooltip({ showDelay, hideDelay, }); const triggerRef useRef(null); const tooltipRef useRef(null); const getTriggerProps () ({ ref: triggerRef, onMouseEnter: showTooltip, onMouseLeave: hideTooltip, }); const getTooltipProps () ({ ref: tooltipRef, onMouseEnter: showTooltip, onMouseLeave: hideTooltip, style: { display: visible ? block : none, }, }); return ( span {...getTriggerProps()}{trigger}/span div classNametooltip {...getTooltipProps()} {tip} /div / ); }使用方式// 文件路径react-demo/App.jsx import Tooltip from ./Tooltip; export default function App() { return ( div Tooltip trigger鼠标悬停我 tip这是一个 React 工具提示 showDelay{300} hideDelay{200} / /div ); }注意一个细节getTooltipProps里用了onMouseEnter: showTooltip这样鼠标从触发元素移动到 Tooltip 浮层上时会触发浮层的mouseenter它的实现是清除隐藏计时器所以浮层不会关闭。当鼠标移出浮层时hideTooltip会启动隐藏计时器浮层延迟关闭。5.4 效果验证在 React 项目中运行后可以看到鼠标悬停触发元素300ms 后出现 Tooltip。鼠标在 300ms 内移出Tooltip 不会出现。鼠标移入已经出现的 TooltipTooltip 保持显示。鼠标移出 Tooltip200ms 后 Tooltip 消失。这和原生 JavaScript 方案的行为是一致的只是复用性和可读性更强。6. Vue 方案自定义指令6.1 指令设计Vue 3 中可以用自定义指令封装 Tooltip 延迟逻辑。指令的好处是使用简单在模板里加一行v-tooltip-delay就可以给任意元素绑定延迟提示。指令需要支持以下配置指令值可以是字符串作为 Tooltip 内容。指令值也可以是对象包含content、showDelay、hideDelay。6.2 指令实现// 文件路径vue-demo/directive.js const tooltipDirective { mounted(el, binding) { const { content, showDelay 300, hideDelay 150 } typeof binding.value string ? { content: binding.value } : binding.value || {}; let showTimer null; let hideTimer null; let tooltipEl null; // 创建 Tooltip 浮层 function createTooltip() { if (tooltipEl) return tooltipEl; tooltipEl document.createElement(div); tooltipEl.className tooltip; tooltipEl.textContent content; document.body.appendChild(tooltipEl); // 鼠标进入浮层时清除隐藏计时器 tooltipEl.addEventListener(mouseenter, () { clearTimeout(hideTimer); }); // 鼠标离开浮层时延迟隐藏 tooltipEl.addEventListener(mouseleave, () { hideTooltip(); }); return tooltipEl; } function positionTooltip() { const elRect el.getBoundingClientRect(); const tipRect tooltipEl.getBoundingClientRect(); const top elRect.top - tipRect.height - 8; const left elRect.left elRect.width / 2 - tipRect.width / 2; tooltipEl.style.top ${top window.scrollY}px; tooltipEl.style.left ${left window.scrollX}px; } function showTooltip() { clearTimeout(hideTimer); showTimer setTimeout(() { const tip createTooltip(); positionTooltip(); tip.classList.add(visible); }, showDelay); } function hideTooltip() { clearTimeout(showTimer); hideTimer setTimeout(() { if (tooltipEl) { tooltipEl.classList.remove(visible); } }, hideDelay); } function onMouseEnter() { showTooltip(); } function onMouseLeave() { hideTooltip(); } el.addEventListener(mouseenter, onMouseEnter); el.addEventListener(mouseleave, onMouseLeave); // 保存事件引用方便卸载时移除监听 el._tooltipHandlers { onMouseEnter, onMouseLeave, getTooltipEl: () tooltipEl, }; }, unmounted(el) { const handlers el._tooltipHandlers; if (handlers) { el.removeEventListener(mouseenter, handlers.onMouseEnter); el.removeEventListener(mouseleave, handlers.onMouseLeave); const tipEl handlers.getTooltipEl(); if (tipEl tipEl.parentNode) { tipEl.parentNode.removeChild(tipEl); } } }, }; export default tooltipDirective;这段代码较长但逻辑很直白createTooltip只创建一次浮层后续复用。positionTooltip每次显示前重新计算位置防止滚动后位置错乱。监听器保存在el._tooltipHandlers上组件卸载时才能正确移除监听并清理 DOM。鼠标进入浮层会清除隐藏计时器所以鼠标从触发元素移到浮层上时提示不会消失。6.3 使用方式在 Vue 组件中注册指令!-- 文件路径vue-demo/App.vue -- template div button v-tooltip-delay{ content: 这是一个 Vue 工具提示, showDelay: 300, hideDelay: 200 } 鼠标悬停我 /button /div /template script setup import tooltipDirective from ./directive; const vTooltipDelay tooltipDirective; /script如果只是简单场景也可以直接传字符串button v-tooltip-delay简单提示内容悬停/buttonVue 指令方案的优点是使用非常轻量不需要为每一个 Tooltip 单独写状态管理缺点是逻辑集中在指令定义里如果业务需要更复杂的提示内容比如带 HTML 结构、操作按钮指令方案会变得笨重。那时我更建议直接用现成的 UI 组件库里的 Tooltip而不是自己维护指令。7. 常见问题与排查思路7.1 问题现象与解决方案问题现象常见原因解决思路Tooltip 闪烁快速划过时能看到一闪而过延迟计时器没有被清除鼠标移出后计时器仍触发显示在mouseleave中调用clearTimeout确认清除的是同一个计时器 ID鼠标从触发元素移到 Tooltip 上时Tooltip 立刻消失没有监听 Tooltip 自身的mouseenter/mouseleave给浮层也绑定隐藏延迟清除逻辑CSStransition-delay设置了但没效果visibility是离散属性不能做过渡动画使用opacity配合visibility并为visibility单独设置延迟Tooltip 位置错乱滚动页面后偏移getBoundingClientRect得到的是视口坐标直接赋值给绝对定位加上window.scrollY和window.scrollX多个元素共用 Tooltip 时内容串了定时器回调里使用的是全局变量target使用事件对象中的currentTarget或把目标元素作为参数传入回调组件销毁后计时器还在执行导致报错没有在unmount或useEffect清理函数中清除计时器React 的 Hook 在useEffect返回清理函数Vue 指令在unmounted钩子中清理鼠标快速经过多个按钮前一个按钮的 Tooltip 在下一个按钮上弹出进入新元素时没有清掉上一个元素的计时器统一使用模块级或ref保存的计时器在mouseenter中先clearTimeout7.2 闪烁问题排查闪烁是最常见的 Tooltip 问题。现象是鼠标快速划过时浮层闪了一下。排查步骤确认是否有多个计时器在同时工作。如果显示计时器和隐藏计时器互相覆盖就会出现“刚显示又隐藏”的结果。在mouseenter中先clearTimeout(hideTimer)在mouseleave中先clearTimeout(showTimer)确保同一时刻只有一个计时器生效。检查 Tooltip 浮层是否被父组件的overflow: hidden裁切导致视觉上“闪了一下又被切掉”。打开浏览器开发者工具的 Event Listener 面板确认事件没有重复绑定。7.3 延迟时间不生效如果你设置了showDelay但实际没有效果检查以下几点变量名是否正确有没有把showDelay和hideDelay搞混。是否在传参时被默认值覆盖。React Hook 中如果传入showDelay{0}注意0是有效值不能用|| 300这种写法要用?? 300或直接判断是否undefined。是否在setTimeout里传入了字符串数字比如300这会导致延迟精度问题。React 中的正确写法export default function useTooltip({ showDelay 300, hideDelay 150 } {}) { // 默认参数只在值为 undefined 时生效0 不会被覆盖 }使用useCallback的依赖数组时也要把showDelay、hideDelay加进去否则延迟参数变化后回调不会更新。8. 最佳实践与工程建议8.1 可访问性要求工具提示不能只依赖鼠标悬停状态因为键盘用户和屏幕阅读器用户无法产生mouseenter事件。建议触发 Tooltip 的元素要能被键盘聚焦比如button或带有tabindex0的元素。监听focus和blur事件让键盘聚焦时也能显示和隐藏提示。提示内容是关键信息时考虑使用aria-describedby关联而不是单纯依赖视觉浮层。浮层的role可以用tooltip让辅助技术能够识别。React Hook 中补充键盘事件处理const keyBind { onFocus: showTooltip, onBlur: hideTooltip, }; return { visible, bind: { onMouseEnter: showTooltip, onMouseLeave: hideTooltip, onFocus: showTooltip, onBlur: hideTooltip, }, };这样鼠标和键盘都能触发 Tooltip。8.2 性能优化当页面上有大量 Tooltip 触发元素时频繁创建和销毁浮层会造成性能压力。建议采用以下策略复用单个 Tooltip 浮层而不是每个触发元素都创建一个浮层。可以利用事件委托在容器上监听mouseover根据event.target的>const tipCache new Map(); function getTipContent(key) { if (tipCache.has(key)) { return Promise.resolve(tipCache.get(key)); } return fetch(/api/tip/${key}) .then((res) res.text()) .then((content) { tipCache.set(key, content); return content; }); }8.3 边界场景处理结合“需要延迟然后需要跳过它”这个主题有几个边界场景值得你专门测试鼠标在延迟期间抖动。用户悬停了 100ms移开又悬停 200ms移开。此时不应该弹出 Tooltip。测试方式是连续快速mouseenter/mouseleave多次确认只可能有一次计时器生效。滚动页面时 Tooltip 粘在元素上。如果页面可滚动Tooltip 显示后用户滚动Tooltip 位置会停留在原视口位置导致视觉上分离。解决办法是在显示时记录触发元素的位置或监听scroll事件重新定位。多级嵌套元素。触发元素内部有子元素鼠标在子元素上移动时会触发父元素的mouseleave。可以使用relatedTarget判断是否仍在触发元素区域内。移动端适配。触屏上没有mouseenter需要改用touchstart或点击事件。移动端的 Tooltip 建议在用户点击元素时切换显示而不是依赖悬停。处理嵌套子元素的示例el.addEventListener(mouseleave, function (event) { const toEl event.relatedTarget; if (el.contains(toEl)) { // 鼠标仍然在触发元素内部不隐藏 return; } hideTooltip(); });8.4 工程建议在大型项目里我不建议每个页面从零手写 Tooltip。优先考虑项目已经使用了 Element Plus、Ant Design、Naive UI 等组件库优先使用组件库自带的 Tooltip并查看它是否支持mouseEnterDelay/mouseLeaveDelay属性。项目对交互有定制要求时再封装一个带延迟能力的公共组件或指令。封装时把延迟参数、内容渲染方式、位置、主题样式都作为可配置属性暴露出去。延迟参数统一维护在常量文件或主题配置里避免每个页面出现300、200这样的魔法数字。写单元测试时重点覆盖“延迟后显示”“延迟中移开不显示”“鼠标进入浮层不关闭”这三个逻辑。Ant Design Tooltip 的示例import { Tooltip } from antd; export default function App() { return ( Tooltip title提示内容 mouseEnterDelay{0.3} mouseLeaveDelay{0.15} button悬停/button /Tooltip ); }组件库已经实现了延迟逻辑开发效率最高。只有当组件库无法满足视觉或交互要求时才需要自定义实现。9. 总结工具提示的延迟交互核心是两件事用setTimeout控制显示时机用clearTimeout实现“跳过”逻辑。CSS 的transition-delay只能做到简单的延迟而真正的“延迟期间移开就不显示”“鼠标进入浮层不关闭”这类交互必须由 JavaScript 来控制。本文分别给出了原生 JavaScript、React Hook、Vue 自定义指令三种实现方式。原生方案适合理解原理React 和 Vue 方案适合业务复用。实际项目中如果你的项目已经有组件库先查组件库 Tooltip 的延迟属性如果是自定义需求再把本文的封装思路应用到自己的组件里。动手实现时建议先用最小示例跑通整体流程再逐步加入键盘事件、嵌套元素、滚动重定位这些边界处理。把“延迟显示”和“跳过”这两个分支测试清楚你的 Tooltip 交互就算真正过关了。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻