MrGlasspoole
MrGlasspoole

Reputation: 445

How can I detect a mouse hover through another element?

I have a area map where i show arrows if an area is hovered (JavaScript).
As you can see in the snippets there is "Kinderland" and "Spacecenter".
What I'm trying to do is that if you hover "Kinderland" and the "Spacecenter" arrow is in front of it (snippet 3) that the "Kinderland" arrow appears.

enter image description here

Here is a JSFiddle:
https://jsfiddle.net/rjq9pu6L/17/

<!doctype html>
<html class="no-js" lang="de">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>Untitled Document</title>

<style>
.none {
display: none;
}

#mapMainWrap {
width: 360px;
height: 150px;
background-image:url(https://i.postimg.cc/rpskZ4GZ/map.png);
}

.map {
z-index:50;
}

.maptrans {
z-index:30;
}

.mapMainArrow {
z-index:10;
}

#mapMainArrows {
width:201px;
height:22px;
position:absolute;
top:0;
left:0;
}

#mapMainArrows.mapMainArea1Arrow {
top:70px;
left:60px;
}

#mapMainArrows.mapMainArea2Arrow {
top:70px;
left:190px;
}
</style>
</head>

<body>

<div id="mapMainWrap">

  <div id="mapMainArrows">
    <img id="mapMainArea1Arrow" class="none mapMainArrow" src="https://i.postimg.cc/wMyQj9KQ/area1-ar.png" width="201" height="22" alt="Area 1">
    <img id="mapMainArea2Arrow" class="none mapMainArrow" src="https://i.postimg.cc/Qdb4PxjF/area2-ar.png" width="201" height="22" alt="Area 2">
  </div>

  <img src="https://i.postimg.cc/ZqNmpdrG/maptrans.png" class="maptrans" width="360" height="150" alt="Map" usemap="#mapmain">
  <map name="mapmain" class="map">
      <area id="mapMainArea1" alt="Area 1" href="javascript:void(0)" coords="60,3,8,46,3,135,23,146,86,148,91,105,133,94,137,7" shape="poly">
      <area id="mapMainArea2" alt="Area 2" href="javascript:void(0)" coords="167,26,163,30,170,37,169,68,151,107,185,123,219,51,196,37" shape="poly">
  </map>

</div>

<script>
const mapMainArrows = document.getElementById('mapMainArrows');
const mapMainArrow = document.getElementsByClassName('mapMainArrow');
var imapMainArrow;
function hideMapMainArrow () {
  for (imapMainArrow = 0; imapMainArrow < mapMainArrow.length; imapMainArrow++) {
    mapMainArrow[imapMainArrow].classList.add("none");
  }
}

// Area 1
const mapMainArea1 = document.getElementById('mapMainArea1');
const mapMainArea1Arrow = document.getElementById('mapMainArea1Arrow');
mapMainArea1.addEventListener('mouseover', function() {
  hideMapMainArrow();
  mapMainArrows.className = "";
  mapMainArrows.classList.add("mapMainArea1Arrow");
  mapMainArea1Arrow.classList.remove("none");
}, false);

// Area 2
const mapMainArea2 = document.getElementById('mapMainArea2');
const mapMainArea2Arrow = document.getElementById('mapMainArea2Arrow');
mapMainArea2.addEventListener('mouseover', function() {
  hideMapMainArrow();
  mapMainArrows.className = "";
  mapMainArrows.classList.add("mapMainArea2Arrow");
  mapMainArea2Arrow.classList.remove("none");
}, false);
</script>
</body>
</html>

Upvotes: 0

Views: 702

Answers (1)

DBS
DBS

Reputation: 9959

Assuming you don't need to be able to click on anything inside the arrows:

You use the CSS rule pointer-events: none; on the arrows, this will prevent the arrows from catching the event and will allow it to pass through to the map underneath (And trigger your mouseover event listener)

The only thing I've changed from your snippet is the CSS for #mapMainArrows

const mapMainArrows = document.getElementById('mapMainArrows');
const mapMainArrow = document.getElementsByClassName('mapMainArrow');
var imapMainArrow;

function hideMapMainArrow() {
  for (imapMainArrow = 0; imapMainArrow < mapMainArrow.length; imapMainArrow++) {
    mapMainArrow[imapMainArrow].classList.add("none");
  }
}

// Area 1
const mapMainArea1 = document.getElementById('mapMainArea1');
const mapMainArea1Arrow = document.getElementById('mapMainArea1Arrow');
mapMainArea1.addEventListener('mouseover', function() {
  hideMapMainArrow();
  mapMainArrows.className = "";
  mapMainArrows.classList.add("mapMainArea1Arrow");
  mapMainArea1Arrow.classList.remove("none");
}, false);

// Area 2
const mapMainArea2 = document.getElementById('mapMainArea2');
const mapMainArea2Arrow = document.getElementById('mapMainArea2Arrow');
mapMainArea2.addEventListener('mouseover', function() {
  hideMapMainArrow();
  mapMainArrows.className = "";
  mapMainArrows.classList.add("mapMainArea2Arrow");
  mapMainArea2Arrow.classList.remove("none");
}, false);
.none {
  display: none;
}

#mapMainWrap {
  width: 360px;
  height: 150px;
  background-image: url(https://i.postimg.cc/rpskZ4GZ/map.png);
}

.map {
  z-index: 50;
}

.maptrans {
  z-index: 30;
}

.mapMainArrow {
  z-index: 10;
}

#mapMainArrows {
  width: 201px;
  height: 22px;
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

#mapMainArrows.mapMainArea1Arrow {
  top: 70px;
  left: 60px;
}

#mapMainArrows.mapMainArea2Arrow {
  top: 70px;
  left: 190px;
}
<div id="mapMainWrap">

  <div id="mapMainArrows">
    <img id="mapMainArea1Arrow" class="none mapMainArrow" src="https://i.postimg.cc/wMyQj9KQ/area1-ar.png" width="201" height="22" alt="Area 1">
    <img id="mapMainArea2Arrow" class="none mapMainArrow" src="https://i.postimg.cc/Qdb4PxjF/area2-ar.png" width="201" height="22" alt="Area 2">
  </div>

  <img src="https://i.postimg.cc/ZqNmpdrG/maptrans.png" class="maptrans" width="360" height="150" alt="Map" usemap="#mapmain">
  <map name="mapmain" class="map">
      <area id="mapMainArea1" alt="Area 1" href="javascript:void(0)" coords="60,3,8,46,3,135,23,146,86,148,91,105,133,94,137,7" shape="poly">
      <area id="mapMainArea2" alt="Area 2" href="javascript:void(0)" coords="167,26,163,30,170,37,169,68,151,107,185,123,219,51,196,37" shape="poly">
  </map>

</div>

Upvotes: 1

Related Questions