I mostly work with PHP. I am not really a JavaScript guy at all, but in this day and age we all end up working with it a bit.
I'm trying to do something that seems like it should be fairly simple. Unfortunately, I am not having any success getting it to work.

I have several links on a page. I have a corresponding number of div's.

.topdiv {
    display:none;
    }
<a href="#" onclick="topdivOpen('topdiv1');return FALSE;">1st Div</a><br />
<a href="#" onclick="topdivOpen('topdiv2');return FALSE;">2nd Div</a><br />
<a href="#" onclick="topdivOpen('topdiv3');return FALSE;">3rd Div</a><br />

<div id="topdiv1" class="topdiv">1st Div</div>
<div id="topdiv2" class="topdiv">2nd Div</div>
<div id="topdiv3" class="topdiv">3rd Div</div>

The div's display in css are all set to "none". When I click a link, I want the corresponding div to display (set css display to "block".)

My script for a single div works perfectly:

function topdivOpen(div)
{
  setDisplay(div);
}

function setDisplay(div)
{
  var obj=document.getElementById(div);
  obj.style.display = (obj.style.display == 'block') ? 'none' : 'block';
}

My problem arises when I try to loop through the div's so that when I click on one, the others (if displayed) get their display set to "none".

This was my most recent attempt:

function topdivOpen(div)
{
  for(var x=0;x<=10;x++)
  {
    var otherDiv = "topdiv"+x;
    if (otherDiv == div)
    {
      setDisplay(div);
    }
    else
    {
      hideDiv(otherDiv);
    }
  }
}

function setDisplay(div)
{
  var obj=document.getElementById(div);
  obj.style.display = (obj.style.display == 'block') ? 'none' : 'block';
}

function hideDive(otherDiv)
{
  var otherobj = document.getElementById(otherDiv);
  if (otherobj)
  {
    otherobj.style.display == 'none';
  }
}

Any thoughts would be welcome!
Thank you.

Recommended Answers

All 5 Replies

firstly if you are going to do lots of js, use a library (i use jquery)
next
i normally use stylesheets to help me out
i have given you a start here

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>tabs</title>
	<meta name="generator" content="TextMate http://macromates.com/">
	<meta name="author" content="no password">
	<!-- Date: 2009-04-21 -->
	<style type="text/css" media="screen">
		.show {
		    display:block;
		    }
		.hide{
			display:none;
		}
	</style>

</head>
<body>
	<a href="#" onclick="testme();return false;">1st Div</a><br />
	<a href="#">2nd Div</a><br />
	<a href="#">3rd Div</a><br />

	<div id="topdiv1" class="hide">1st Div</div>
	<div id="topdiv2" class="hide">2nd Div</div>
	<div id="topdiv3" class="hide">3rd Div</div>
	
<script type="text/javascript" charset="utf-8">
		
	
	var mydivs = document.getElementsByTagName('div');
	var divlen = mydivs.length;
	alert(divlen);
	function testme(){
	  	for (var i=0;i<divlen;i++) {
		    mydivs[i].className ='show';
		}
	}

</script>	
	
</body>
</html>

by the way in my example above script goes at bottom of page

The simplest way to do this, is to fake it by their ids.
In this demo i used the individual id of the anchor element's, making it as my pointer to get specific div's on the page. Code is as follows:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css href="#internal"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>JavaScript Demo</title>
<style id="internal" type="text/css" media="screen">
/* <![CDATA[ */
.div-hide {
  display : none; }
.div-show {
  display : block; }
/* ]]> */
</style>
<script type="text/javascript">
// <![CDATA[
var control, display, div, showHide;

var control = function() {
showHide = function( div ) {
   div = ( document.getElementById ) ? document.getElementById( div ) : document.all[ div ];
   try {
   div.className = ( div.className === "div-hide" ) ? "div-show" : "div-hide";
   } catch( error ) {
   return div.style.display = ( div.style.display === "none" ) ? "block" : "none";
  }
}; 

display = function( e ) {
   e = e ? e : window.event;
   a = e.target ? e.target : e.srcElement;
   if (( a.parentNode.parentNode.nodeName.toLowerCase() === "ol" ) && ( a.nodeName.toLowerCase() === "a" )) {
   num = parseInt( a.id.match(/\d+$/));
   showHide("topdiv" + num); 
   } else { return false; }
 }; 
return { display : display }
}();

document.onclick = control.display;
   
// ]]>
</script>
</head>
<body>
<div id="main">
<ol>
<li><a id="d1" href="javascript:void(0)">1st DIV</a></li>
<li><a id="d2" href="javascript:void(0)">2nd DIV</a></li>
<li><a id="d3" href="javascript:void(0)">3rd Div</a></li>
</ol>
<div id="topdiv1" class="div-hide">DIV One</div>
<div id="topdiv2" class="div-hide">DIV Two</div>
<div id="topdiv3" class="div-hide">DIV Three</div>
</div> 
</body>
</html>

Hope it helps you in what you need. Good day...

Bigtalk,

Your code will compact down nicely, like this:

function topdivOpen(n){
for(var i=1; i<=3; i++){
[INDENT]var divRef = document.getElementById("topdiv"+i);
if(divRef){
[INDENT]divRef.style.display = (i==n) ? 'block' : 'none';[/INDENT]
}
[/INDENT]
return false;
}

The secret is to pass in simple integer values from the HTML onclick calls, so you can test integer against integer in the loop inside your function:

<a href="" onclick="return topdivOpen(1);">1st Div</a><br />
<a href="" onclick="return topdivOpen(2);">2nd Div</a><br />
<a href="" onclick="return topdivOpen(3);">3rd Div</a><br />
<div id="topdiv1" class="topdiv">1st Div</div>
<div id="topdiv2" class="topdiv">2nd Div</div>
<div id="topdiv3" class="topdiv">3rd Div</div>

As johnyN says above, use a library if you are doing lots of (or really tricky) stuff, but for simple stuff like this avoid bloatware. Libs can be real monsters!

Essential's code is neat if you want to keep your XHTML really clean. The code is still quite compact, but at the cost of being inpenetrable by novice JavaScripters. Essential has invested quite some time acquiring the knowledge to do it his way.

You pays you money and takes your pick. As with everything JavaScript, there are many ways to skin your web page.

Airshow

commented: Airshow responded very susinctly and tidily. +2

Thank you so much for the responses!

I was able to deduce the errors in my script by analyzing the code you all posted here (before you posted Airshow:) .)

My else statement was stopping my loop. I was also getting an obj is null error.

This is what I came up with:

function topdivOpen(div)
{
  var mydivs = document.getElementsByTagName('div');
  var divlen = mydivs.length;
  
  for(var x=1;x<=divlen;x++)
  {
    var otherDiv = "topdiv"+x;
    if (otherDiv == div) { setDisplay(div); continue; }
    setDisplay(otherDiv);
  }
}

function setDisplay(div)
{
  var obj = document.getElementById(div);
  if (obj) { obj.style.display = (obj.style.display == 'block') ? 'none' : 'block'; }
}

It's not quite as compact and tidy as the help you have given Airshow, but it remove's the limit on the number of "topdiv"'s I can use in a page. It also allows me to click on a given link a second time to re-hide the div.

Library's - I'm not doing a great deal of JavaScript right now, but I'm sure I will need to get acquainted with them. JQuery? Scriptaculous?

Again, thank you very much, all of you.

If you still think my script needs help, don't hesitate to let me know. I'm always trying to make things better and learn.

You can throttle scope of document.getElementsByTagName(); by first wrapping the HTML block in question in a wrapping div:

<div id="topDivWrapper">
[INDENT]<div id="topdiv1" class="topdiv">1st Div</div>
<div id="topdiv2" class="topdiv">2nd Div</div>
<div id="topdiv3" class="topdiv">3rd Div</div>[/INDENT]
</div>

then, in your Javascript, find all the contained divs with document.getElementById('topDivWrapper').getElementsByTagName('div') .

Even better is to use DOM method [I]element[/I].childNodes() to create an array of elements (divs in this case) within the wrapper, then traverse the array with your loop. This is very efficient as it will loop precisely the correct number of times - no overscan. I'll let you read that up for yourself.

Airshow

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.