Reputation: 43
Scenario:
I have a state map of the USA. Over top of the state map, I have manufactured an area map to make each state a clickable link. Over each state, I have a <div>
with absolute position and CSS styling to make the <div>
look like a callout or tooltip box -- containing information about the address and website of the head office in each specific state.
So, yes, I have 50 different <div>
s with absolute positioning that are currently set to "visibility:hidden".
What I am trying to accomplish:
When you click on a specific link from the area map, the <div>
for that US state will appear in the appropriate location. Furthermore, when you click on the exact same state the <div>
will hide, or when you click on a different state the all of the <div>
s hide, and the proper <div>
for the new state will appear.
I would prefer to do this in simple Javascript (not Jquery) as ultimately the page will be loaded in a website with a Drupal CMS.
Please help. I'd rather not code each state as a button and write fifty different segments of javascript code.
Upvotes: 2
Views: 2141
Reputation: 65391
I would change your design slightly and use a single div
for displaying the state info. Store the state info another way (I used dataset-
values in my sample and used the state name as the class
) and load it dynamically into your info div
. This makes it easier to show/hide when clicking on the same state, and is less markup. Also, use display: none;
to hide the state info div
so it's removed from the layout.
Demo: http://jsfiddle.net/ThinkingStiff/WYLzY/
Script:
var areas = document.getElementsByTagName( 'area' );
for( var index = 0; index < areas.length; index++ ) {
areas[index].addEventListener( 'click', function ( event ) {
var info = document.getElementById( 'info' ), display;
if( info.hasClass( this.dataset.state ) ) {
display = info.style.display == 'none' ? 'block' : 'none';
} else {
info.setAttribute( 'class', this.dataset.state );
display = 'block';
}
info.innerHTML = this.dataset.address;
info.style.display = display;
}, false );
};
Element.prototype.hasClass = function ( className ) {
return this.className.split( ' ' ).indexOf( className ) > -1;
};
HTML:
<div id="map-view">
<img id="map" src="http://thinkingstiff.com/images/matt.jpg" usemap="#map"/>
<map name="map">
<area shape="rect" coords="0,0,50,50" data-state="california"
data-address="123 One St<br />Chronic Town, CA 99190" href="#" />
<area shape="rect" coords="50,50,150,150" data-state="oregon"
data-address="345 Two St<br />Bird On It, OR 89190" href="#" />
</map>
<div id="info"></div>
<div>
CSS:
#map {
height: 245px;
width: 180px;
}
#map-view {
position: relative;
}
#info {
background-color: white;
display: none;
position: absolute;
z-index: 1;
}
.california {
left: 50px;
top: 25px;
}
.oregon {
left: 150px;
top: 125px;
}
Upvotes: 1
Reputation: 64953
So you have three main problems to solve:
You can enumerate the links with the .getElement* functions. Depending on the markup of your list, it might take a more walk around before you get the elements you want; jQuery would really help in simplifying the .getElement* functions.
Next, you attach onclick handler to each of those links. You can do this by assigning to the element.onclick attribute. This is the key part to writing "unobtrusive javascript", which are used heavily in jQuery.
Finally, you need a way to map the links to the divs. The simplest is to build the id of the target div using the links' id. So, for example, if a link's id is 'io' (for Iowa) then you will toggle the visibility of the div whose id is 's_io' by simply prepending 's_' to the link's id. Alternatively, you can use a hash map or HTML 5 custom data attribute to store the id of the target div or you can use str.replace or str.substring.
You can see this in action in this jsfiddle, another version using image map.
Upvotes: 1