如何使用单个 Vanilla JS 工具提示 div 来显示 100 多个不同的工具提示?

How to use a single Vanilla JS tooltip div to display 100+ different tooltips?

我制作了一个 HTML/JS 网站,我想在该网站上显示图标的工具提示,如下所示:

我想看的:

  1. 当我悬停在任何东西上时,我希望 div 隐藏在 CSS 中。
  2. 当我将鼠标悬停在另一个图标上时,我希望 div 获得正确的信息。

我想如何编码:

像这样使用单个顶级 DIV:

<div id="circle" class="circleTT">
<div id="circlecontent" class="civBoxTT">
  <h3><b>Villager (SAMPLE: NOT LIVE DATA)</b></h3>Gathers Wood, Food, Stone, and Gold. Builds and repairs buildings
  and can repair
  siege engines and naval units. - Weak in combat<br><img src="img/resourcefoodicon.png">50<br><img
    src="img/house.png">1<br><img src="img/timetobuild.png">20s<br><br>
</div>

为什么?因为使用更简单的工具提示时有两个问题:要么我无法在工具提示中显示图像,要么工具提示位于 DIV 内并会向该部分添加滚动条。因为父 div 能够弃牌,据我所知这是无法修复的。

然后,像这样在 Javascript 中添加鼠标悬停:

const isHover = e => e.parentElement.querySelector(':hover') === e;

  const myDiv = document.getElementById('tooltip');
  /*for (var i = 0; i < myDiv.length; i++) {*/
  document.addEventListener('mousemove', function checkHover() {
    const hovered = isHover(myDiv);
    if (hovered !== checkHover.hovered) {
      if (hovered) {
        document.getElementById('circlecontent').innerHTML = "<h3><b>Villager (age: 1)</b></h3>Gathers Wood, Food, Stone, and Gold. Builds and repairs buildings and can repair siege engines and naval units. - Weak in combat<br><img src=\"img/resourcefoodicon.png\">50<br><img src=\"img/house.png\">1<br><img src=\"img/timetobuild.png\">20s<br><br>";
      }
      else {
        document.getElementById('circlecontent').innerHTML = "";
      }
      checkHover.hovered = hovered;
    }
  });
  /*}*/

  let circle = document.getElementById('circle');

  const onMouseMove = (e) => {
    circle.style.left = e.pageX + 5 + 'px';
    circle.style.top = e.pageY + 5 + 'px';
  }

  document.addEventListener('mousemove', onMouseMove);

这都是来自其他人如何制作类似工具提示的示例

但是,当我简单地将此鼠标悬停 Javascript 应用于所有元素时,网页变得非常慢,可能是因为每次鼠标移动它接收鼠标悬停状态 100-200 次。

用简单的 Vanilla JS 编写代码的好方法是什么?

经过多次试验和错误后,它像这样修复:

///////////////////////////////////////////////////
  // SHOW tooltips
  ///////////////////////////////////////////////////
  let tooltipContainer = document.getElementById('tooltipContainer');
  const tooltipBox = document.getElementById('tooltipBox');
  document.addEventListener('mousemove', function checkHover(e) {
    tooltipContainer.style.left = getWidth() > e.pageX + 400 ? e.pageX + 2 + 'px' : e.pageX - 402 + 'px';
    tooltipContainer.style.top = e.pageY + 2 + 'px';
    const allTooltips = document.getElementsByClassName('tooltip');
    for (var i = 0; i < allTooltips.length; i++) {
      if (allTooltips.item(i).querySelector(':hover')) {
        tooltipBox.innerHTML = allTooltips.item(i).lastChild.innerHTML; tooltipBox.style.display = "block"; return;
      }
    }
    tooltipBox.innerHTML = ""; tooltipBox.style.display = "none";
  });

基本上每次鼠标移动时都会有一个 MouseMove 事件检查鼠标位置,调整 DIV 的位置,最后遍历所有带有工具提示的元素以检查是否有任何悬停。