0

So i have multiple buttons that is showing when it's clicked. But i'm having a hard time hiding the content if another button is clicked.


The Javascript code looks like this

function portFunction() {
    var e = document.getElementById("test2").style;
    if(!e.display | e.display == "none"){
        e.display = "block";
    }
else{
    e.display = "none";
    }
}

And the html

<nav>
     <ul>   
        <li onclick="portFunction();"><a href="#">Portfolio</a></li>
        <li onclick="blogFunction();"><a href="#">Blog</a></li>
     </ul>
    </nav>

How can i make it so if another button is clicked, it hides the content for the last button that was open and display the new button content?

EDIT Snippet code, ok so if you click on Portfolio some text will be displayed. But if you click on Blog some other text will be displayed, but the text from Portfolio will still be displayed. What i want is, if you click the Portfolio button and then the Blog button, the text from portfolio should go away. And i want this for every button.

function blogFunction() {
	var e = document.getElementById("test").style;
	if(!e.display | e.display == "none"){
		e.display = "block";
	}
else{
	e.display = "none";
	}
}

function portFunction() {
	var e = document.getElementById("test2").style;
	if(!e.display | e.display == "none"){
		e.display = "block";
	}
else{
	e.display = "none";
	}
}
@import url(http://fonts.googleapis.com/css?family=Open+Sans);
.center{
font: 100% open sans, sans-serif;
margin:0;
padding:0;
}
#test{
display:none;
height:20%;
width:20%;
z-index:11;
position:absolute;
left:50%;
right: 50%;
}
.testText{
color:red;
z-index:11;
}
#test2{
display:none;
height:20%;
width:20%;
z-index:11;
position:absolute;
left:50%;

}
<nav>
  <ul>
    <li class="current"><a href="#">Home</a></li>
    <li onclick="portFunction();"><a href="#">Portfolio</a></li>
    <li onclick="blogFunction();"><a href="#">Blog</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
    <li><a href="#">Preview</a></li>
  </ul>
</nav>
<div class="center">
	<div id="test">
		<h1 class="testText">
			Test
		</h1>
	</div>
	<div id="test2">
		<h1 class="testText">
			Test2
		</h1>
	</div> 
</div>

10
  • Can you put up a fiddle ? Commented Sep 12, 2015 at 17:03
  • Where is element with ID test2? Commented Sep 12, 2015 at 17:07
  • Added snippet to the post and explained. Appreciate any suggestions :) Commented Sep 12, 2015 at 17:23
  • Let me clarify. You WANT the text that is displayed on click of "Portfolio" to go away/hide when you click on a new link - example: the link "Blog" and display the text associated with the link "blog" ? Is that correct ? Commented Sep 12, 2015 at 17:35
  • Yes, In the snippet you see that if you click the Portfolio button and then the Blog button the content from both buttons are displayed, wich is what i don't want. I'm gonna make this for every button so i need to figure out how i can do it. When one button is clicked it should display the content for that button, but when another button is clicked it should hide the content from the other button and display the new content for that button. :) Commented Sep 12, 2015 at 17:40

3 Answers 3

2

A simpler way to do this would be to use classes and jQuery's eq() something like this:

$('.section-link').click(function() {
  var cur = $('.section-link').index($(this)); // get the index of the clicked link
  $('.section-display').removeClass('active'); // hide all of the sections
  $('.section-display').eq(cur).addClass('active'); // show the section at the same index of the clicked link 
});
.section-display:not(.active) {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
  <ul>
    <li class="section-link"><a href="#">Portfolio</a>
    </li>
    <li class="section-link"><a href="#">Blog</a>
    </li>
  </ul>
</nav>
<br>
<br>
<div class="section-display active">Section One</div>
<div class="section-display">Section Two</div>

In response to your comment, Let's take the code line by line:

First, the CSS rule .section-display:not(.active) { display: none; } hides every element that has the class section-display, unless it also has the class active. This makes all of the divs hidden but allows you to add the classactive if you want a particular section to be shown by default.

In the jQuery, $('.section-link').click(function() { }); is a click handler. Basically, it says when someone clicks on an element that has the class section-link, run the code in this block

Inside the handler, the variable $(this) refers to a jQuery object that represents the element that was clicked (in your case a link).

The first line, var cur = $('.section-link').index($(this)); says, gather all of the elements that have the class section-link (all of you links) into an array and give me the index of the one that was clicked. So now we know that the user clicked the 2nd link for example.

The next line $('.section-display').removeClass('active'); removes the class active from all of the divs that have the class section-display which hides all the divs because of the css rule

On the next line $('.section-display').eq(cur).addClass('active');, $('.section-display') gathers all of the divs that have the class section-display into an array (these are the divs with the content). After that .eq(cur) selects the div from the array that is at the same index as the link that was clicked. And finally .addClass('active') adds the class active to the element which displays the4 element because of the css rule.

So now, clicking on the first section-link element will show the first section-display div and hide all others. Clicking on the second section-link element will show the second section-display div and hide all others. And so on...

Sign up to request clarification or add additional context in comments.

2 Comments

Why your solution is BAD, 1. because the order of the links decides which section to show.. change the order of the links and it breaks. 2. You use CSS to hide the content, but it's still in the DOM
@ webdeb, yeah you've had your say and I understand your point of view, have a great day
0

I added a callLastFunc() function, it saves and calls previous function, to hide the content added by previous function call.

var lastCalled = null;

function callLastFunc(arg) {
  if (arg[0])
    return;

  if (lastCalled)
    lastCalled("byCallPrev");
  lastCalled = arg.callee;
}

function blogFunction() {
	var e = document.getElementById("test").style;
	if(!e.display | e.display == "none"){
		e.display = "block";
	}
else{
	e.display = "none";
	}
  callLastFunc(arguments);
}

function portFunction() {
	var e = document.getElementById("test2").style;
	if(!e.display | e.display == "none"){
		e.display = "block";
	}
else{
	e.display = "none";
	}
  callLastFunc(arguments);
}
@import url(http://fonts.googleapis.com/css?family=Open+Sans);
.center{
font: 100% open sans, sans-serif;
margin:0;
padding:0;
}
#test{
display:none;
height:20%;
width:20%;
z-index:11;
position:absolute;
left:50%;
right: 50%;
}
.testText{
color:red;
z-index:11;
}
#test2{
display:none;
height:20%;
width:20%;
z-index:11;
position:absolute;
left:50%;

}
<nav>
  <ul>
    <li class="current"><a href="#">Home</a></li>
    <li onclick="portFunction();"><a href="#">Portfolio</a></li>
    <li onclick="blogFunction();"><a href="#">Blog</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
    <li><a href="#">Preview</a></li>
  </ul>
</nav>
<div class="center">
	<div id="test">
		<h1 class="testText">
			Test
		</h1>
	</div>
	<div id="test2">
		<h1 class="testText">
			Test2
		</h1>
	</div> 
</div>

1 Comment

Could the user that down voted my answer explain the reason? I think I've provided a working solution that solves the question, with as less change as possible to existing code, and without introducing jQuery. If using JQuery this code can be rewritten totally in different way.
-1

Hmm, you would be better to use a framework, but this is what you want right? This example make use of vanillaJS Framework, which is very powerful out of the box ;)

// lib.js
sitesContent = {};
// blog.js
sitesContent['blog'] = "Blog content"; // You can use templates like handlebars
// portfolio.js
sitesContent['portfolio'] = "Portfolio content"; // Better to use templates
// app.js
function navAction(site) {
    document.getElementById('content').innerHTML = sitesContent[site];
}
navAction('portfolio'); // Means load portfolio when loaded first time
<nav>
     <ul>   
        <li><a onclick="navAction('portfolio')" href="#">Portfolio</a></li>
        <li><a onclick="navAction('blog')" href="#">Blog</a></li>
     </ul>
</nav>
<div id="content"></div>

3 Comments

So you're telling me that you are going to have all of your html content for each section written in your javascript file in an object called sitesContent ....rather than just hiding and showing the divs as was asked? ....Fair enough....
I edited the post with a snippet, but just out of curiosity. What does the navAction('port); do? I don't know what the 'port' is ._.
@andyduly98 port is what you call your portfolio so far. I edited it now. navAction is one function which handles your current content, depend on what you click, see the html snippet to understand how it is related to the sitesContent. Additionally look that you can separate the files for blog or portfolio, they don't have to be all in one place.. At last but not least, you should take a look on some templating engines like handlebars.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.