我已经构建了一个SVG映射,您可以在其中将鼠标悬停在左侧单独的名称列表上,这将触发工具提示.或者将鼠标悬停在 map 上的编号图标上,也会触发工具提示.

但是,我无法成功地让工具提示相对于每个编号图标重新定位.

var iconPos = myicon.getBoundingClientRect();
  mypopup.style.left = (iconPos.right + 20) + "px";
  mypopup.style.top = (window.scrollY + iconPos.top - 60) + "px";
  mypopup.style.display = "block";

我以前试图使用上面的代码,但它使工具提示的位置为top: 6451px;+.

我希望工具提示出现在具有类selected的编号图标(map__plot__item)的中心.

下面是我创建的一个演示,以显示它当前如何与位于右上角的工具提示一起工作.也是JS Fiddle here美元.

$( ".map__list__item" ).on( "mouseover", function() {
        var tooltipCopy = $(this).html();
        $(this).addClass('selected');
        $(this).siblings('li').removeClass('selected');
        $('#' + $(this).data('map')).addClass('selected');
        $('#' + $(this).data('map')).siblings('g').removeClass('selected');
        $("#mypopup").show().html(tooltipCopy);
    });

    $( ".map__list__item" ).on( "mouseout", function() {
        $(this).removeClass('selected');
        $(this).siblings('li').removeClass('selected');
        $('#' + $(this).data('map')).removeClass('selected');
        $('#' + $(this).data('map')).siblings('g').removeClass('selected');
        $("#mypopup").hide().empty();
    });

    $('.map__plot__item').on( "mouseover", function() {
        var tooltipCopy =  $(this).data('list');
        $(this).addClass('selected');
        $(this).siblings('g').removeClass('selected');
        $("#mypopup").show().html(tooltipCopy);
    });

    $('.map__plot__item').on( "mouseout", function() {
        $(this).removeClass('selected');
        $(this).siblings('g').removeClass('selected');
        $("#mypopup").hide().empty();
    });
body {
  margin: 0;
  padding: 0;
}
#top-section {
  height: 250px;
  background: red;
}

h1 {
  color: white;
  text-align: center;
  font-size: 40px;
  line-height: 40px;
  font-family: Arial;
}
#map-wrapper {
  position: relative;
  width: 100%;
}

#mapNavigation {
  width: 200px;  
  flex-shrink: 0
}

#mapNavigation li {
  line-height: 25px;
}

.d-flex {
  display: flex;
}

svg {
  width: 100%;
}

#mypopup {
  width: 200px;
  height: 20px;
  padding: 10px;
  font-family: Arial, sans-serif;
  font-size: 18px;
  color: $dark;
  background-color: white;
  border-radius: 6px;
  position: absolute;
  display: none;
  top: 0;
  right: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="top-section">
  <h1>
    Heading here
  </h1>
</div>
<div class="d-flex">
  <div id="mapNavigation">
    <ol>
      <li id="restaurant-list-01" class="map__list__item" data-map="restaurant-01">
       Name here 01
      </li>
      <li id="restaurant-list-02" class="map__list__item" data-map="restaurant-02">
        Name here 02
      </li>
      <li id="restaurant-list-03" class="map__list__item" data-map="restaurant-03">
        Name here 03
      </li>
      <li id="restaurant-list-04" class="map__list__item" data-map="restaurant-04">
        Name here 04
      </li>
      <li id="restaurant-list-05" class="map__list__item" data-map="restaurant-05">
        Name here 05
      </li>
      <li id="restaurant-list-06" class="map__list__item" data-map="restaurant-06">
        Name here 06
      </li>
      <li id="restaurant-list-07" class="map__list__item" data-map="restaurant-07">
        Name here 07
      </li>
      <li id="restaurant-list-08" class="map__list__item" data-map="restaurant-08">
        Name here 08
      </li>
    </ol>
  </div>
  <div id="map-wrapper">
    
<svg width="100%"  viewBox="0 0 1336 942" fill="none">
<g id="Layer_2">
    <rect width="1336" height="942" fill="#D9D9D9"/>
</g>
<g id="Layer_1">
    <g id="restaurant-05" data-list="Name here 05" class="map__plot__item">
        <circle cx="554" cy="336" r="36" fill="#B93333"/>
        <path d="M547.5,340.8l3.8-0.4c0.1,0.9,0.4,1.6,1,2.1c0.5,0.5,1.2,0.8,1.9,0.8c0.8,0,1.5-0.3,2-1
            c0.6-0.7,0.8-1.6,0.8-3c0-1.2-0.3-2.2-0.8-2.8c-0.5-0.6-1.3-0.9-2.1-0.9c-1.1,0-2.1,0.5-3,1.5l-3.1-0.5l2-10.4H560v3.6h-7.2
            l-0.6,3.4c0.9-0.4,1.7-0.6,2.6-0.6c1.7,0,3.1,0.6,4.3,1.9c1.2,1.2,1.8,2.8,1.8,4.8c0,1.6-0.5,3.1-1.4,4.4
            c-1.3,1.8-3.1,2.7-5.4,2.7c-1.8,0-3.4-0.5-4.5-1.5C548.4,343.9,547.7,342.5,547.5,340.8z" fill="white" />
    </g>
    <g id="restaurant-03" data-list="Name here 03" class="map__plot__item">
        <circle cx="732" cy="320" r="36" fill="#B93333"/>
        <path d="M725.3,324.7l3.7-0.5c0.1,0.9,0.4,1.7,1,2.2c0.5,0.5,1.1,0.8,1.9,0.8c0.8,0,1.5-0.3,2-0.9
            c0.5-0.6,0.8-1.4,0.8-2.4c0-1-0.3-1.7-0.8-2.3c-0.5-0.6-1.2-0.8-1.9-0.8c-0.5,0-1.1,0.1-1.8,0.3l0.4-3.1c1,0,1.8-0.2,2.4-0.7
            c0.5-0.5,0.8-1.1,0.8-1.9c0-0.7-0.2-1.2-0.6-1.6s-0.9-0.6-1.6-0.6c-0.7,0-1.2,0.2-1.7,0.7c-0.5,0.5-0.7,1.1-0.8,2l-3.5-0.6
            c0.2-1.2,0.6-2.2,1.1-2.9c0.5-0.7,1.2-1.3,2.1-1.7c0.9-0.4,1.9-0.6,3-0.6c1.9,0,3.4,0.6,4.5,1.8c0.9,1,1.4,2.1,1.4,3.3
            c0,1.8-1,3.2-2.9,4.2c1.1,0.2,2.1,0.8,2.7,1.7c0.7,0.9,1,1.9,1,3.1c0,1.8-0.6,3.3-1.9,4.5c-1.3,1.2-2.9,1.9-4.8,1.9
            c-1.8,0-3.3-0.5-4.5-1.6C726.1,327.7,725.5,326.4,725.3,324.7z" fill="white"/>
    </g>
    <g id="restaurant-02" data-list="Name here 02" class="map__plot__item">
        <circle cx="988" cy="240" r="36" fill="#B93333"/>
        <path d="M994.4,246.4v3.6h-13.5c0.1-1.3,0.6-2.6,1.3-3.8c0.7-1.2,2.2-2.8,4.3-4.8c1.7-1.6,2.8-2.7,3.2-3.3
            c0.5-0.8,0.8-1.6,0.8-2.4c0-0.9-0.2-1.5-0.7-2c-0.5-0.5-1.1-0.7-1.9-0.7c-0.8,0-1.4,0.2-1.9,0.7s-0.7,1.3-0.8,2.4l-3.8-0.4
            c0.2-2.1,0.9-3.6,2.1-4.6c1.2-0.9,2.7-1.4,4.5-1.4c2,0,3.5,0.5,4.7,1.6c1.1,1.1,1.7,2.4,1.7,4c0,0.9-0.2,1.8-0.5,2.6
            c-0.3,0.8-0.8,1.7-1.5,2.6c-0.5,0.6-1.3,1.4-2.5,2.6c-1.2,1.1-2,1.9-2.3,2.2c-0.3,0.4-0.6,0.7-0.8,1.1H994.4z" fill="white"/>
    </g>
    <g id="restaurant-04" data-list="Name here 04" class="map__plot__item">
        <circle cx="1094" cy="494" r="36" fill="#B93333"/>
        <path d="M1094.9,504v-4h-8.2v-3.4l8.7-12.7h3.2v12.7h2.5v3.4h-2.5v4H1094.9z M1094.9,496.6v-6.9l-4.6,6.9H1094.9z" fill="white"/>
    </g>
    <g id="restaurant-01" data-list="Name here 01" class="map__plot__item">
        <circle cx="916" cy="664" r="36" fill="#B93333"/>
        <path d="M919.2,674h-3.8v-14.5c-1.4,1.3-3.1,2.3-5,2.9v-3.5c1-0.3,2.1-0.9,3.3-1.9c1.2-0.9,2-2,2.4-3.2h3.1V674z" fill="white"/>
    </g>
    <g id="restaurant-06" data-list="Name here 06" class="map__plot__item">
        <circle cx="416" cy="748" r="36" fill="#B93333"/>
        <path d="M422.4,742.9l-3.7,0.4c-0.1-0.8-0.3-1.3-0.7-1.7c-0.4-0.4-0.9-0.5-1.5-0.5c-0.8,0-1.5,0.4-2.1,1.1
            c-0.6,0.7-0.9,2.2-1.1,4.6c1-1.1,2.1-1.7,3.6-1.7c1.6,0,3,0.6,4.1,1.8c1.1,1.2,1.7,2.8,1.7,4.7c0,2.1-0.6,3.7-1.8,4.9
            c-1.2,1.2-2.7,1.9-4.6,1.9c-2,0-3.7-0.8-5-2.4c-1.3-1.6-2-4.2-2-7.7c0-3.7,0.7-6.3,2-7.9c1.4-1.6,3.1-2.4,5.3-2.4
            c1.5,0,2.8,0.4,3.8,1.3C421.5,740,422.1,741.2,422.4,742.9z M413.7,751.2c0,1.2,0.3,2.2,0.9,2.9c0.6,0.7,1.2,1,2,1
            c0.7,0,1.3-0.3,1.8-0.8c0.5-0.6,0.7-1.5,0.7-2.7c0-1.3-0.3-2.3-0.8-2.9c-0.5-0.6-1.1-0.9-1.9-0.9c-0.7,0-1.4,0.3-1.9,0.9
            C414,749.3,413.7,750.1,413.7,751.2z" fill="white"/>
    </g>
    <g id="restaurant-07" data-list="Name here 07" class="map__plot__item">
        <circle cx="260" cy="220" r="36" fill="#B93333"/>
        <path d="M253.4,213.8v-3.6h13.1v2.8c-1.1,1.1-2.2,2.6-3.3,4.6c-1.1,2-2,4.1-2.6,6.4c-0.6,2.2-0.9,4.2-0.9,6h-3.7
            c0.1-2.8,0.6-5.6,1.7-8.5c1.1-2.9,2.5-5.5,4.3-7.7H253.4z" fill="white"/>
    </g>
    <g id="restaurant-08" data-list="Name here 08" class="map__plot__item">
        <circle cx="490" cy="548" r="36" fill="#B93333"/>
        <path d="M486.7,547.2c-1-0.4-1.7-1-2.2-1.7c-0.4-0.7-0.7-1.5-0.7-2.4c0-1.5,0.5-2.7,1.6-3.7c1-1,2.5-1.5,4.5-1.5
            c1.9,0,3.4,0.5,4.4,1.5c1.1,1,1.6,2.2,1.6,3.7c0,0.9-0.2,1.8-0.7,2.5c-0.5,0.7-1.2,1.3-2,1.7c1.1,0.4,2,1.1,2.5,2
            c0.6,0.9,0.9,1.8,0.9,3c0,1.9-0.6,3.4-1.8,4.5c-1.2,1.2-2.7,1.7-4.7,1.7c-1.8,0-3.3-0.5-4.6-1.4c-1.4-1.1-2.1-2.7-2.1-4.6
            c0-1.1,0.3-2.1,0.8-3C484.7,548.4,485.5,547.7,486.7,547.2z M487.5,543.3c0,0.8,0.2,1.4,0.6,1.8c0.4,0.4,1,0.6,1.7,0.6
            c0.7,0,1.3-0.2,1.8-0.6c0.4-0.4,0.7-1,0.7-1.8c0-0.7-0.2-1.3-0.7-1.7c-0.4-0.4-1-0.7-1.7-0.7c-0.7,0-1.3,0.2-1.8,0.7
            C487.7,542,487.5,542.6,487.5,543.3z M487.1,551.9c0,1.1,0.3,1.9,0.8,2.5c0.5,0.6,1.2,0.9,2,0.9c0.8,0,1.4-0.3,2-0.8
            c0.5-0.6,0.8-1.4,0.8-2.5c0-0.9-0.3-1.7-0.8-2.3c-0.5-0.6-1.2-0.9-2-0.9c-0.9,0-1.6,0.3-2.1,1
            C487.4,550.4,487.1,551.1,487.1,551.9z" fill="white"/>
    </g>
</g>
</svg>

  <div id="mypopup"></div>
  </div>
</div>

推荐答案

  • 将您的HTML属性简化为仅使用data-map(而不是类、ID等)
  • 计算放置弹出窗口的位置的百分比,获取SVG的ViewBox的宽度/高度和目标<g> getBBox xy位置

const $popup = $("#mypopup");
const $liAll = $("#mapNavigation li[data-map]");
const $svg = $("#map-wrapper svg");
const $gAll = $("g[data-map]", $svg);

$("[data-map]").on("mouseenter mouseleave", function(ev) {
  const id = $(this).data("map");
  const $li = $(`#mapNavigation li[data-map="${id}"]`);
  const $g = $(`g[data-map="${id}"]`, $svg);
  const desc = $li.text();

  $liAll.add($gAll).removeClass("selected");

  if (ev.type === "mouseenter") {
    
    $li.add($g).addClass("selected");
    const {width, height} = $svg.prop("viewBox").baseVal;
    const {x, y} = $g[0].getBBox();

    $popup
      .show()
      .text(desc)
      .css({
        left: `${x / width * 100}%`,
        top: `${y / height * 100}%`
      });
    
  } else {
    
    $li.add($g).removeClass("selected");
    $popup.hide().text("");
    
  }
});
body {
  margin: 0;
  padding: 0;
  font: 1rem/1.4 Arial, sans-serif;
}

#top-section {
  height: 250px;
  background: red;
}

h1 {
  color: white;
  text-align: center;
  font-size: 40px;
  line-height: 40px;
  font-family: Arial;
}

#map-wrapper {
  position: relative;
  width: 100%;
  background: green;
  align-self: start; /* NEEDED */
}

#mapNavigation {
  flex: 1 0 auto;
  li {
    &.selected {
      color: red;
    }
  }
}

svg {
  display: block;
  width: 100%;
  
  g.selected {
    circle{
      fill: #fff;
    }
    text {
      fill: #000;
    }
  }
  
  text {
    font: 2.2em/1 sans-serif;
    text-anchor: middle;
    fill: #fff;
  }
}

#mypopup {
  position: absolute;
  display: none;
  width: 200px;
  height: 20px;
  padding: 10px;
  background-color: white;
  border-radius: 6px;
  translate: -50% -100%;
  top: 0;
  right: 0;
}

.d-flex {
  display: flex;
}
<div id="top-section">
  <h1>Heading here</h1>
</div>
<div class="d-flex">
  <div id="mapNavigation">
    <ol>
      <li data-map="restaurant-01">Name here 01</li>
      <li data-map="restaurant-02">Name here 02</li>
      <li data-map="restaurant-03">Name here 03</li>
      <li data-map="restaurant-04">Name here 04</li>
      <li data-map="restaurant-05">Name here 05</li>
      <li data-map="restaurant-06">Name here 06</li>
      <li data-map="restaurant-07">Name here 07</li>
      <li data-map="restaurant-08">Name here 08</li>
    </ol>
  </div>
  <div id="map-wrapper">
    <svg viewBox="0 0 1336 942" fill="none">
      <g id="Layer_2">
        <rect width="1336" height="942" fill="#D9D9D9"/>
      </g>
      <g id="Layer_1">
        <g data-map="restaurant-05">
          <circle cx="554" cy="336" r="36" fill="#B93333"/>
          <text x="554" y="336" dy="0.4em">5</text>
        </g>
        <g data-map="restaurant-03">
          <circle cx="732" cy="320" r="36" fill="#B93333"/>
          <text x="732" y="320" dy="0.4em">3</text>
        </g>
        <g data-map="restaurant-02">
          <circle cx="988" cy="240" r="36" fill="#B93333"/>
          <text x="988" y="240" dy="0.4em">2</text>
        </g>
        <g data-map="restaurant-04">
          <circle cx="1094" cy="494" r="36" fill="#B93333"/>
          <text x="1094" y="494" dy="0.4em">4</text>    
        </g>
        <g data-map="restaurant-01">
          <circle cx="916" cy="664" r="36" fill="#B93333"/>
          <text x="916" y="664" dy="0.4em">1</text>
        </g>
        <g data-map="restaurant-06">
          <circle cx="416" cy="748" r="36" fill="#B93333"/>
          <text x="416" y="748" dy="0.4em">6</text>
        </g>
        <g data-map="restaurant-07">
          <circle cx="260" cy="220" r="36" fill="#B93333"/>
          <text x="260" y="220" dy="0.4em">7</text>
        </g>
        <g data-map="restaurant-08">
          <circle cx="490" cy="548" r="36" fill="#B93333"/>
          <text x="490" y="548" dy="0.4em">8</text>
        </g>
      </g>
    </svg>

    <div id="mypopup"></div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>

Javascript相关问答推荐

是否有方法在OpenWeatherMap API中获取过go 的降水数据?

Klaro与Angular的集成

如何在RTK上设置轮询,每24小时

使用下表中所示的值初始化一个二维数组

react—router v6:路由没有路径

Angular material 拖放堆叠的牌副,悬停时自动展开&

如何禁用附加图标点击的v—自动完成事件

给定一个凸多边形作为一组边,如何根据到最近边的距离填充里面的区域

如何在ASP.NET中使用Google Charts API JavaScript将条形图标签显示为绝对值而不是负值

rxjs插入延迟数据

如何发送从REST Api收到的PNG数据响应

第二次更新文本输入字段后,Reaction崩溃

使用VUE和SCSS的数字滚动动画(&;内容生成)

触发异步函数后不能显示数据

如何使本地html页面在重新加载时保持当前可隐藏部分的打开状态?

重新呈现-react -筛选数据过多

如何在每隔2分钟刷新OKTA令牌后停止页面刷新

计算对象数组中属性的滚动增量

Played link-Initialize.js永远显示加载符号

验证Java脚本函数中的两个变量