You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何制作与原生title属性样式一致的可悬停、Esc关闭Tooltip

问题描述

我想要复刻原生title属性的Tooltip外观与交互效果,要求:

  • Tooltip支持悬停(鼠标移到Tooltip上时不会消失)
  • 可通过按Esc键关闭Tooltip

目前我制作的自定义Tooltip无法实现悬停效果,且样式和原生的不一致,附上现有代码寻求帮助:

现有HTML代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>Tooltip</title>
  </head>
  <body>
    <span class="tooltip-trigger" aria-describedby="tooltip-text"
      >Hover over me</span
    >
    <div id="tooltip-text" class="tooltip-text" role="tooltip">
      This is the tooltip text
    </div>
    <script src="script.js"></script>
  </body>
</html>

现有CSS代码

.tooltip-text {
    visibility: hidden;
    position: absolute;
    background-color: #000;
    color: #fff;
    padding: 4px;
    z-index: 1;
}

.tooltip-trigger{
    cursor: pointer;
}

.tooltip-trigger:hover .tooltip-text {
    visibility: visible;
}

现有JS代码

const tooltipTrigger = document.querySelector(".tooltip-trigger");
const tooltipText = document.querySelector(".tooltip-text");

tooltipTrigger.addEventListener("mouseenter", showTooltip);
tooltipTrigger.addEventListener("mouseleave", hideTooltip);
tooltipText.addEventListener("keydown", dismissTooltip);

function showTooltip() {
  tooltipText.style.visibility = "visible";
}

function hideTooltip() {
  tooltipText.style.visibility = "hidden";
}

function dismissTooltip(event) {
  if (event.keyCode === 27) {
    tooltipText.style.visibility = "hidden";
  }
}

解决方案

核心问题拆解

  1. 悬停失效:Tooltip和触发元素是兄弟节点,鼠标从触发元素移到Tooltip时会触发mouseleave;同时CSS选择器.tooltip-trigger:hover .tooltip-text不生效,因为Tooltip不是触发元素的子元素。
  2. 样式不符:原生Tooltip有特定的淡色背景、边框、字体大小和间距,现有样式完全偏离。
  3. Esc关闭无效:Tooltip默认无焦点,绑定在它身上的keydown事件无法触发。

修改后的完整代码

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="styles.css" />
    <title>Tooltip</title>
  </head>
  <body>
    <!-- 将Tooltip改为触发元素的子元素,保证hover状态延续 -->
    <span class="tooltip-trigger" aria-describedby="tooltip-text">
      Hover over me
      <div id="tooltip-text" class="tooltip-text" role="tooltip">
        This is the tooltip text
      </div>
    </span>
    <script src="script.js"></script>
  </body>
</html>

CSS

/* 完全匹配原生Tooltip样式 */
.tooltip-text {
    visibility: hidden;
    position: absolute;
    background-color: #ffffcc; /* 原生淡黄色背景 */
    color: #000;
    padding: 5px 8px;
    border: 1px solid #000; /* 原生带黑色细边框 */
    border-radius: 3px;
    font-size: 12px;
    z-index: 1000;
    white-space: nowrap; /* 原生不自动换行 */
    margin-top: 8px; /* 和触发元素保持原生间距 */
}

.tooltip-trigger{
    cursor: pointer;
    position: relative; /* 让Tooltip相对于触发元素定位 */
}

/* 触发元素hover显示Tooltip,Tooltip自身hover也保持显示 */
.tooltip-trigger:hover .tooltip-text,
.tooltip-text:hover {
    visibility: visible;
}

JS

const tooltipTrigger = document.querySelector(".tooltip-trigger");
const tooltipText = document.querySelector(".tooltip-text");

// 监听全局键盘事件,确保Esc键能触发关闭
document.addEventListener("keydown", dismissTooltip);

// 鼠标离开触发元素时,判断是否移到Tooltip上,避免误关闭
tooltipTrigger.addEventListener("mouseleave", function(e) {
    if (!tooltipText.contains(e.relatedTarget)) {
        tooltipText.style.visibility = "hidden";
    }
});

// 鼠标离开Tooltip时关闭
tooltipText.addEventListener("mouseleave", function() {
    tooltipText.style.visibility = "hidden";
});

function dismissTooltip(event) {
    // 使用event.key替代已废弃的keyCode,兼容性更好
    if (event.key === "Escape") {
        tooltipText.style.visibility = "hidden";
    }
}

关键修改说明

  • DOM结构调整:把Tooltip嵌套进触发元素内,既让CSS hover选择器生效,也方便相对定位。
  • 样式对齐:完全照搬原生Tooltip的背景色、边框、字体和间距,还原原生视觉效果。
  • 悬停逻辑修复:通过判断鼠标离开的目标元素,确保移到Tooltip上时不会关闭;同时给Tooltip自身加hover状态兜底。
  • Esc功能修复:监听全局键盘事件,确保无论焦点在哪,Esc都能关闭Tooltip,同时用event.key替代过时的keyCode。

内容的提问来源于stack exchange,提问作者thelonelyCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:50:33