6 Replies - 8181 Views - Last Post: 21 October 2011 - 09:11 AM

#1 Bertan  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 20-October 11

Problem with show different divs onclick

Posted 20 October 2011 - 10:22 AM

I have some problem getting this script to work. I want to be able to show the content for the link I am clicking on.
I have put the classes in a for loop making the links work as they should, however the content always gets the last [i] value. This results in always showing the last content no matter which link I click on.

Any help on this would be highly appreciated as I been banging my head against the wall with this problem the last few days. Note, I'm trying to make it work unobtrusive.

Thanks,

HTML:
<!DOCTYPE html>
<html>
	<head>
		<title></title>
		<meta charset="UTF-8" />
		<link href="css/stylesheet.css" rel="stylesheet" type="text/css" />
		<script src="javascript/script.js" type="text/javascript"></script>
	</head>
	<body>
		<div id="wrapper">		
			<div id="content">		
			
				<a href="#" class="showText">Slide down</a>
				<div class="text">
					<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. 
					Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet 
					egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan 
					porttitor, facilisis luctus, metus</p>
				</div>
				
				<a href="#" class="showText">Slide down</a>
				<div class="text">
					<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. 
					Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet 
					egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan 
					porttitor, facilisis luctus, metus</p>
				</div>		
				
				<a href="#" class="showText">Slide down</a>
				<div class="text">
					<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. 
					Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet 
					Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque 
					egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan 
					Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque 
					egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan 			
					porttitor, facilisis luctus, metus</p>
				</div>	
				
			</div>
		</div>
	</body>
</html>



CSS:
#wrapper {
	width: 960px;
	margin: 0 auto;
}
#content {
	background: #234343;
	height: 600px;
	width: 700px;
	float: left;
	padding: 20px;
}

.showText {
	display: block;
	color: #282828;
	border: 1px solid #282828;
	width: 400px;
	background: #bbb;
	padding: 5px;
}

.text {
	overflow: hidden;
	width: 400px;
	background: #fff;
	border: 1px solid #282828;
	padding: 5px;
	display: none;
}



Javascript:
onload=function(){

	showContent();
	
	function showContent() {
		var texts = document.getElementsByClassName("text");
		var showTexts = document.getElementsByClassName("showText");
		var y = 0;

		for (var i = 0; i < showTexts.length; i++) {
			var showText = showTexts[i];
			
			var text = texts[i];
			text.style.display = "block";
			var firstTextHeight = text.offsetHeight;
			text.style.display = "none";
			
			showText.onclick = showCommments;	
		}

				
		function showCommments() {
			text.style.display = "block";
			var textHeight = text.offsetHeight;
			if (firstTextHeight < textHeight){
				slideUp();
			} else {
				slideDown();
			}
			
			function slideDown(){
				y++;
				if(y <= firstTextHeight){
					text.style.height = y + "px";
					setTimeout(slideDown, 1);
				}
				showText.innerHTML = "Hide";
			}
				
			function slideUp(){
				y--;
				if(y >= 0){
					text.style.height = y + "px";
					setTimeout(slideUp, 1);
				} else {
					showText.innerHTML = "Show";
					text.style.display = "none"; 
				}				
			}
		}		
	}
}



Is This A Good Question/Topic? 0
  • +

Replies To: Problem with show different divs onclick

#2 sas1ni69  Icon User is offline

  • D.I.C Regular
  • member icon

Reputation: 85
  • View blog
  • Posts: 431
  • Joined: 04-December 08

Re: Problem with show different divs onclick

Posted 20 October 2011 - 05:39 PM

If you take a look at your code right now, all the 3 paragraphs have the same class names and they're not assigned individual IDs. The js engine would not be able to understand which div you are referring to. You will need to assign separate IDs to tell it that you are referring to an individual div.

I hope this helps :)
Was This Post Helpful? 0
  • +
  • -

#3 satis  Icon User is offline

  • D.I.C Head

Reputation: 82
  • View blog
  • Posts: 231
  • Joined: 26-May 11

Re: Problem with show different divs onclick

Posted 21 October 2011 - 06:06 AM

An alternative would be to use some DOM traversal so you don't have to reference specific elements. This makes the script more scalable... you can add more items without having to make any changes to the script at all.

Here's a simple example. I've used jquery because it makes dealing with events much easier.

<html>
<head>
	<style type='text/css'>
		.showText{
			color: #000099;
			cursor: pointer;
		}
		.text{
		
		}
	</style>
	<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js'></script>
	<script type='text/javascript'>
		function initialize(){
			//attach event handlers to all the text fields
			$('.showText').click(show);
			//set them all to display: none - there are other ways to do this in jquery
			$('.text').css('display', 'none');
		}
		function show(){
			//get an array of all the text divs
			var divs = $('.showText');
			//loop through them
			for(var i=0; i<divs.length; i++){
				var text = $('.text')[i]; // this gets a reference to the text field associated with each showText div
				if(divs[i] == this){
					//this is the currently clicked div
					if(text.style.display == 'none')	//is the text element hidden?
						text.style.display = '';	//if so, unhide it
					else
						text.style.display = 'none';	//else, hide it
				}
				else{
					//this is not our currently clicked element, so just hide it
						text.style.display = 'none';
				}
			}
		}
		
		$(window).load(initialize);
	</script>
</head>
<body>

<div class='showText'>Down</div>
<div class='text'>This is the text from div1</div>
<div class='showText'>Down</div>
<div class='text'>This is the text from div 2</div>
<div class='showText'>Down</div>
<div class='text'>This is the text from div 3</div>

</body>
</html>


In my example, you can keep adding showText/text pairs and it'll keep working without need to make any changes to the javascript.

*edit*
meh, I'm not really using node traversal in that, I'm just using getElementsByClassName and parallel arrays, basically... here's an altered example that actually uses node traversal. Normally I'd just use nextSibling, but in this case the HTML has textNodes scattered between the HTML elements, so I have a little while loop to make up for it.

	<script type='text/javascript'>
		function initialize(){
			//attach event handlers to all the text fields
			$('.showText').click(show);
			//set them all to display: none - there are other ways to do this in jquery
			$('.text').css('display', 'none');
		}
		function show(){
			//get an array of all the text divs
			var divs = $('.showText');
			//loop through them
			for(var i=0; i<divs.length; i++){
				var text = divs[i].nextSibling;
				while(text.nodeType != 1){
					text = text.nextSibling;
				}
				if(divs[i] == this){
					//this is the currently clicked div
					if(text.style.display == 'none')	//is the text element hidden?
						text.style.display = '';	//if so, unhide it
					else
						text.style.display = 'none';	//else, hide it
				}
				else{
					//this is not our currently clicked element, so just hide it
						text.style.display = 'none';
				}
			}
		}
		
		$(window).load(initialize);
	</script>

This post has been edited by satis: 21 October 2011 - 06:11 AM

Was This Post Helpful? 0
  • +
  • -

#4 Bertan  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 20-October 11

Re: Problem with show different divs onclick

Posted 21 October 2011 - 07:59 AM

Thanks, I will look into your solution and see if I can get it to work without libraries :)
Was This Post Helpful? 0
  • +
  • -

#5 satis  Icon User is offline

  • D.I.C Head

Reputation: 82
  • View blog
  • Posts: 231
  • Joined: 26-May 11

Re: Problem with show different divs onclick

Posted 21 October 2011 - 08:29 AM

Yea, it's possible. I just use jquery for simplification purposes. The biggest problem is that IE doesn't support addEventListener, so you have to write special code. That's really what drove me to use jquery. That and getElementsByClassName not being supported in IE. Man, I hate IE.
Was This Post Helpful? 0
  • +
  • -

#6 Bertan  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 20-October 11

Re: Problem with show different divs onclick

Posted 21 October 2011 - 08:57 AM

I dont care about IE right now just want to get this working in chrome and firefox, it's a private project nothing that is going public.

By the way, the problem about nextSibling and textnodes could be solved by using nextElementSibling, right?
Was This Post Helpful? 0
  • +
  • -

#7 satis  Icon User is offline

  • D.I.C Head

Reputation: 82
  • View blog
  • Posts: 231
  • Joined: 26-May 11

Re: Problem with show different divs onclick

Posted 21 October 2011 - 09:11 AM

Hmm, yea, looks like it would indeed. I wasn't even aware that was a method. Nice catch.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1