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

jQuery实现圆形鼠标悬停时标签固定定位的技术问题

解决圆形悬停标签固定在上方的问题

我明白你的问题了——当前标签跟着鼠标移动,长文本时还会和圆形重叠,你希望它固定在红色圆形的正上方,不管鼠标在圆形哪个位置都不动对吧?

问题根源

现在的代码是用e.pageX和e.pageY来定位标签,所以标签会跟着鼠标走;而且长文本时标签宽度增加,就容易和下方的圆形重叠。我们需要改成基于圆形元素的位置来固定标签,而不是依赖鼠标坐标。

解决方案

下面是修改后的代码,我会标注关键修改点:

修改后的JS代码

$(function(){
  $('circle').mouseenter(function(e){
    const circle = $(this);
    const circleId = circle.attr('id');
    const regionObject = {
      "philadelphia" : "Philadelphia, city in pennsylvania",
    };
    // 创建标签元素
    const div = $(`<div class="current_region"> 
      <div class="current_region_box"> 
        <p>${regionObject[circleId]}</p> 
      </div> 
      <div class="region_pointer"></div> 
    </div>`);
    
    // 先将标签添加到DOM,确保能正确获取宽度
    div.appendTo(document.body);
    
    // 获取圆形元素的位置和尺寸
    const circleOffset = circle.offset();
    const circleRadius = parseInt(circle.attr('r'));
    // 计算标签的位置:固定在圆形正上方,居中对齐
    const labelWidth = div.find('.current_region_box').outerWidth();
    const labelTop = circleOffset.top - div.outerHeight() - 10; // 10是标签与圆形的间距
    const labelLeft = circleOffset.left + circleRadius - (labelWidth / 2);
    
    div.css({
      "display": "block",
      "left": labelLeft + 'px',
      "top": labelTop + 'px'
    });
  }).mouseout(function(){
    $('body').find('.current_region').remove();
  });
});

优化后的CSS代码

.current_region { 
  position: absolute; 
  white-space: nowrap; /* 可选:防止文本换行导致宽度变化,根据需求调整 */
}
.current_region_box {
  position: relative; z-index: 10;
  border-radius: 30px; background: white;
  box-shadow: 0px 2px 6px 1px rgba(18, 40, 112, 0.5);
  padding: 4px 12px;
}
.current_region_box p { 
  font-family: firagolight; 
  font-size: 15px; 
  margin: 0; /* 去掉默认p标签的margin,避免高度计算误差 */
}
.region_pointer {
  position: absolute; z-index: 9;
  bottom: -12px; /* 调整指针位置,确保指向圆形顶部 */
  right: 0; left: 0; 
  margin: auto;
  width: 25px; height: 25px;
  background: white; border-radius: 5px;
  transform: rotate(45deg);
  box-shadow: 0px 0px 4px -1px grey;
}

HTML代码(无需修改,保持原样即可)

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <!-- Font Awesome -->
  <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
  <!-- Developer CSS -->
  <link rel="stylesheet" type="text/css" href="./map.css">
  <!-- Jquery-->
  <script src="js/jquery-3.4.1.min.js"></script>
</head>
<body>
  <div class="example" style="text-align: center; padding-top: 50px; cursor: pointer; " >
    <svg height="100" width="100">
      <circle id="philadelphia" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
      Sorry, your browser does not support inline SVG.
    </svg>
  </div>
  <!--Boostrap JS-->
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity=" sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity=" sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  <script src="./map.js"></script>
</body>
</html>

关键修改说明

  1. 定位逻辑变更:不再依赖鼠标坐标,而是通过circle.offset()获取圆形元素在页面的绝对位置,计算出标签固定在圆形正上方的坐标,确保标签位置不再跟随鼠标移动。
  2. 宽度适配:先将标签添加到DOM再获取实际宽度,保证长文本时标签也能完美居中对齐,不会偏移。
  3. CSS细节优化:去掉p标签默认margin避免高度计算误差,调整指针的bottom值让它准确指向圆形顶部,可选添加white-space: nowrap防止文本换行(如果不需要换行的话)。

这样修改后,不管鼠标在圆形哪个位置悬停,标签都会固定在圆形正上方,长文本也不会和圆形重叠啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 12:32:50