javascripttooltipimagemap

Image map - how display tooltip on hover and only when mouse stops


I'm a javascript beginner and I got stuck having a problem with displaying the tooltip (as a div) correctly for image map.

I want the tooltip appears only when the cursor is over an element (defined within the tags) and only when the mouse stops on it.

I don't know why the added addEventListener method causes the tooltip to be displayed also after the onmouseout event is executed, i.e. when the cursor leaves a given element.

https://jsfiddle.net/1b5mf06j/2/

function myFuncHide(el) {

 var tooltip = document.getElementById('myTooltip');
 tooltip.style.display = 'none';

}

function myFunc (el) {
var tooltip = document.getElementById('myTooltip');
var timeout;
document.addEventListener('mousemove', moving);

function moving() {

  if (timeout) clearTimeout(timeout);
  timeout = setTimeout(mouseStop, 450);}
  
function mouseStop() {
var tooltip = document.getElementById('myTooltip');
tooltip.style.display = 'block';}
 
}
#myTooltip {
  padding: 15px;
  background: rgba(0,0,0,.5);
  color: white;
  position: absolute;
  display: none;
}
<img src="http://tutorialspoint.com//images/usemap.gif" class="locations-map-full" alt="" usemap="#map">
<map name="map" id="locations-map">
 
<area shape="circle" coords="73,168,32" class="tooltip" onmouseover="myFunc(this)" onmouseout="myFuncHide(this)"/>
<area shape="poly" coords="74,0,113,29,98,72,52,72,38,27" class="tooltip" onmouseover="myFunc(this)" onmouseout="myFuncHide(this)"/>
<area shape="rect" coords="22,83,126,125" class="tooltip" onmouseover="myFunc(this)" onmouseout="myFuncHide(this)"/>
</map>
                    
               
<div id="myTooltip"> <p><img src="http://getbootstrap.com/apple-touch-icon.png" width="150px" height="150px" style="border: 1px solid #9b9999;"></p> </div>


Solution

  • Your mousemove listener is on the document object and stays in effect regardless of where the mouse goes (in fact, additional listeners keeps getting piled on as you enter the area).

    Here's a code rearrangement that adds cleanup to the mouseout event. It removes the listener and clears the timeout variable.

    Also, I've done a little general code cleanup for you. Better function names. Removed some redundancy (remember DRY - Don't Repeat Yourself). Indentation. :)

    var timeout;
    var tooltipEl = document.getElementById('myTooltip');
    
    function mouseMoving() {
      if (timeout) clearTimeout(timeout);
      
      timeout = setTimeout(function() {
         tooltipEl.style.display = 'block';
      }, 450);
    }
    
    function ingress () {
      document.addEventListener('mousemove', mouseMoving);
    }
    
    function egress() {
      // cleanup
      if (timeout) clearTimeout(timeout)
      document.removeEventListener("mousemove", mouseMoving)
      
      tooltipEl.style.display = 'none';
    }
    

    You can see the working version here: https://jsfiddle.net/alucheni/xmf5tjeh/25/.