简体   繁体   中英

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

I've cooked up a HTML/JS website on which I want to show tooltips for icons like so: 在此处输入图像描述

What I want to see:

  1. When I hover over nothing I want the div to be hidden in CSS.
  2. When I hover over another icon I want the div to get correct info.

How I want to code it:

Using a single top-level DIV like so:

<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>

Why? Because when using simpler tooltips had two problems: either I could not show images within the tooltip OR the tooltip would be inside the DIV and would add scrollbars to that part. Because the parent div is able to fold this was not fixable as far as my knowledge goes.

Then, adding mouseover in Javascript like so:

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);

This is all from samples how other people made similar Tooltips

However, when I simply apply this Mouseover Javascript to all elements then the webpage becomes extremely slow, probably because it is receiving the mouseover state 100-200 times per mouse-move.

What is a good clean way to code this in simple Vanilla JS?

After much more trial and error fixed it like so:

///////////////////////////////////////////////////
  // 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";
  });

Basically every time the mouse moves there is a single MouseMove event that checks the mouse position, adjusts the position of the DIV, and finally runs through all elements with tooltip to check if any is hovered.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM