I'm creating basically a tooltip for SVG groups. I'm not using the title=>tooltip built in because I want to have richer content eventually that plain text can't support.
I've used a div element to render the text. My intention was for the div to be visible when the group is hovered and hidden when no group has focus. Also for the div to move to proximity to the group.
While the innerHTML is updated, the visibility and position are not.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
svg {
max-width: 100%;
height: auto;
display: block;
g {
transform-origin: 50% 50%;
path {
fill: #ccc;
transition: background-color 200ms ease-in;
&:hover {fill: #c00;}
}
&:hover {cursor: pointer;}
}
}
#popup {
position: absolute;
background-color: white;
border: 1px solid #ccc;
padding: 10px;
font-size: 14px;
}
</style>
<script>
// -------------
var popup = null;
// -------------
document.addEventListener("DOMContentLoaded", function () {
document.getElementById("map").addEventListener("mousemove", function(event) {
doMove(event);
});
popup = document.getElementById("popup");
popup.setAttribute("visibility", "hidden");
});
// -------------
function doEnter(which){
popup.innerHTML = which.id;
popup.setAttribute("visibility", "visible");
};
function doLeave(which){
popup.setAttribute("visibility", "hidden");
};
function doMove(what){
popup.setAttribute("style", "left: "+what.pageX + 5+"; top: "+what.pageY + 5);
};
// -------------
</script>
</head>
<body>
<div id="map">
<div id="popup" visibility="hidden" style="left: 0; top: 0"></div>
<svg xmlns="http://www.w3.org/2000/svg" width="918" height="582" viewBox="0 0 918.4 582.5">
<g id="California" onmouseenter="doEnter(this)" onmouseleave="doLeave(this)"><path d="M122.7,385.9,103,383.2l-10-1.5-.5-1.8v-9.4l-.3-3.2-2.6-4.2-.8-2.3-3.9-4.2L82,351.9l-2.7-.2-3.2-.8-.3-1,1.5-.6-.6-3.2L75.2,344l-4.8-.8-3.9-2.1-1.1-2.3L62.8,334l-2.9-3.1H57l-3.9-2.1L48.6,327l-4.2-.5L42,323.8l.5-1.9,1.8-7.1.8-1.9v-2.4l-1.6-1-.5-2.9L41.5,304l-3.4-5.8-1.3-3.1-1.5-4.7-1.6-5.3-3.2-4.4-.5-2.9.8-3.9h1.1l2.1-1.6,1.1-3.6-1-2.7-2.7-.5-1.9-2.6-2.1-3.7-.2-8.2.6-1.9.6-2.3.5-2.4-5.7-6.3V236l.3-.5.3-3.2-1.3-4-2.3-4.8L17.5,219l-1.8-3.9,1-3.7.6-5.8,1.8-3.1.3-6.5-1.1-3.6-1.6-4.2L14,184l.8-3.2,1.5-4.2,1.8-.8.3-1.1,3.1-2.6,5.2-11.8.2-7.4,1.69-4.9,38.69,11.8,25.6,6.6-8,31.3-8.67,33.1L88.84,250,131,312.3l17.1,26.1-.4,3.1,2.8,5.2,1.1,5.4,1,1.5.7.6-.2,1.4-1.4,1-3.4,1.6-1.9,2.1-1.7,3.9-.5,4.7-2.6,2.5-2.3,1.1-.1,6.2-.6,1.9,1,1.7,3,.3-.4,1.6-1.4,2-3.9.6ZM48.8,337l1.3,1.5-.2,1.3-3.2-.1-.6-1.2-.6-1.5Zm1.9,0,1.2-.6,3.6,2.1,3.1,1.2-.9.6-4.5-.2-1.6-1.6Zm20.7,19.8,1.8,2.3.8,1,1.5.6.6-1.5-1-1.8-2.7-2-1.1.2v1.2ZM70,365.5l1.8,3.2,1.2,1.9-1.5.2-1.3-1.2a9.72,9.72,0,0,1-.7-1.9v-2.2Z" transform="translate(-9 -6.4)"></path></g>
<g id="Nebraska" onmouseenter="doEnter(this)" onmouseleave="doLeave(this)"><path d="M470.3,204.3l-1-2.3-.5-1.6-2.9-1.6-4.8-1.5-2.2-1.2-2.6.1-3.7.4-4.2,1.2-6-4.1-2.2-2-10.7.6L388,189.9l-35.6-2.2-4.3,43.7,33.1,3.3-1.4,21.1,21.7,1,40.6,1.2,43.8.6h4.5l-2.2-3-2.6-3.9.1-2.3-1.4-2.7-1.9-5.2-.4-6.7-1.4-4.1-.5-5-2.3-3.7-1-4.7-2.8-7.9-1-5.3Z" transform="translate(-9 -6.4)"></path></g>
</svg>
</div>
</body>
</html>
Some issues:
visibility
is not an HTML atttribute, but a CSS style, so in your HTML you shouldn't have that as an attribute, nor should you use setAttribute("visibility", "hidden")
. That will not achieve what you want. Instead set the style.visibility
property.
As on mouse movement you set the whole style
HTML attribute, the previous fix would be nullified again on any mouse movement. It is better practice to set the position via style.left
and style.top
assignments, so you only touch those two style attributes, not resetting anything else.
When you set left
and right
to non-zero values, you should append the unit of measure, like px
.
Here is your script with those fixes applied:
// -------------
var popup = null;
// -------------
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("map").addEventListener("mousemove", doMove);
popup = document.getElementById("popup");
popup.style.visibility = "hidden";
});
// -------------
function doEnter(which) {
popup.innerHTML = which.id;
popup.style.visibility = "visible";
};
function doLeave(which) {
popup.style.visibility = "hidden";
};
function doMove(what) {
popup.style.left = (what.pageX + 5) + "px";
popup.style.top = (what.pageY + 5) + "px";
};
// -------------
svg {
max-width: 100%;
height: auto;
display: block;
g {
transform-origin: 50% 50%;
path {
fill: #ccc;
transition: background-color 200ms ease-in;
&:hover {
fill: #c00;
}
}
&:hover {
cursor: pointer;
}
}
}
#popup {
position: absolute;
background-color: white;
border: 1px solid #ccc;
padding: 10px;
font-size: 14px;
}
<div id="map">
<div id="popup" style="left: 0; top: 0"></div>
<svg xmlns="http://www.w3.org/2000/svg" width="918" height="582" viewBox="0 0 918.4 582.5">
<g id="California" onmouseenter="doEnter(this)" onmouseleave="doLeave(this)"><path d="M122.7,385.9,103,383.2l-10-1.5-.5-1.8v-9.4l-.3-3.2-2.6-4.2-.8-2.3-3.9-4.2L82,351.9l-2.7-.2-3.2-.8-.3-1,1.5-.6-.6-3.2L75.2,344l-4.8-.8-3.9-2.1-1.1-2.3L62.8,334l-2.9-3.1H57l-3.9-2.1L48.6,327l-4.2-.5L42,323.8l.5-1.9,1.8-7.1.8-1.9v-2.4l-1.6-1-.5-2.9L41.5,304l-3.4-5.8-1.3-3.1-1.5-4.7-1.6-5.3-3.2-4.4-.5-2.9.8-3.9h1.1l2.1-1.6,1.1-3.6-1-2.7-2.7-.5-1.9-2.6-2.1-3.7-.2-8.2.6-1.9.6-2.3.5-2.4-5.7-6.3V236l.3-.5.3-3.2-1.3-4-2.3-4.8L17.5,219l-1.8-3.9,1-3.7.6-5.8,1.8-3.1.3-6.5-1.1-3.6-1.6-4.2L14,184l.8-3.2,1.5-4.2,1.8-.8.3-1.1,3.1-2.6,5.2-11.8.2-7.4,1.69-4.9,38.69,11.8,25.6,6.6-8,31.3-8.67,33.1L88.84,250,131,312.3l17.1,26.1-.4,3.1,2.8,5.2,1.1,5.4,1,1.5.7.6-.2,1.4-1.4,1-3.4,1.6-1.9,2.1-1.7,3.9-.5,4.7-2.6,2.5-2.3,1.1-.1,6.2-.6,1.9,1,1.7,3,.3-.4,1.6-1.4,2-3.9.6ZM48.8,337l1.3,1.5-.2,1.3-3.2-.1-.6-1.2-.6-1.5Zm1.9,0,1.2-.6,3.6,2.1,3.1,1.2-.9.6-4.5-.2-1.6-1.6Zm20.7,19.8,1.8,2.3.8,1,1.5.6.6-1.5-1-1.8-2.7-2-1.1.2v1.2ZM70,365.5l1.8,3.2,1.2,1.9-1.5.2-1.3-1.2a9.72,9.72,0,0,1-.7-1.9v-2.2Z" transform="translate(-9 -6.4)"></path></g>
<g id="Nebraska" onmouseenter="doEnter(this)" onmouseleave="doLeave(this)"><path d="M470.3,204.3l-1-2.3-.5-1.6-2.9-1.6-4.8-1.5-2.2-1.2-2.6.1-3.7.4-4.2,1.2-6-4.1-2.2-2-10.7.6L388,189.9l-35.6-2.2-4.3,43.7,33.1,3.3-1.4,21.1,21.7,1,40.6,1.2,43.8.6h4.5l-2.2-3-2.6-3.9.1-2.3-1.4-2.7-1.9-5.2-.4-6.7-1.4-4.1-.5-5-2.3-3.7-1-4.7-2.8-7.9-1-5.3Z" transform="translate(-9 -6.4)"></path></g>
</svg>
</div>