1

I am creating a accordion with use of pure JavaScript. Initailly I have shown content of only first section. Then by using JavaScript I am showing content on clicking sections.

This works well but when I click on section1 it does not hide because active class is still there.

<!DOCTYPE html>
<html>
<head>
<style>
.main {
    background-color: #eee;
    width:350px;
    color: #444;   
    padding: 18px;  
    border: none;
    text-align: left;
    font-size: 15px;

}

.main.active,.main:hover {
    background-color: #ddd;
}

div.panel {
    padding: 0 18px;
   background-color: white;
   display:none;
   width:350px;


}
.active{
    display: block !important;

}

div.panel.show {
    display: block;
}
div.panel.hide {
    display: none;
}
</style>
</head>
<body>
<div class="main">Section 1</div>
<div class="panel active">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<div class="main">Section 2</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<div class="main">Section 3</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<script>
var acc = document.getElementsByClassName("main");
var i;
for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function(){    
      this.nextElementSibling.classList.toggle("show");     
  }
}
</script>

</body>
</html>
4
  • 1
    stackoverflow.com/questions/10960573/… Here is how to check if any element has a class. Commented Jun 15, 2016 at 8:00
  • Can you use jQuery instead or is it pure JS only? Commented Jun 15, 2016 at 8:00
  • @Roysh It is possible without jQuery also. Commented Jun 15, 2016 at 8:00
  • Are you only trying to remove active class? Commented Jun 15, 2016 at 8:04

4 Answers 4

2

You can try something like this:

Logic:

  • Check if current clicked section is open or close and save it. This will be use to toggle state.
  • Hide all open sections.
  • If current section is visible, don't do anything. If not, show it.

JSFiddle

function registerEvents() {
  var sections = document.querySelectorAll(".main");
  for (var i = 0; i < sections.length; i++) {
    sections[i].addEventListener("click", toggleSection)
  }
}

function toggleSection(e) {
  var ele = e.target.nextElementSibling;
  var isNotVisible = ele.className.indexOf("active") < 0;
  hideAllPanels();
  if (isNotVisible)
    addClass(ele, "active");
}

function hideAllPanels() {
  var panels = document.querySelectorAll(".panel.active");
  for (var i = 0; i < panels.length; i++) {
    panels[i].className = panels[i].className.replace("active", "");
  }
}

function addClass(el, _class) {
  el.className += " " + _class;
}

(function init() {
  registerEvents();
})()
.main {
  background-color: #eee;
  width: 350px;
  color: #444;
  padding: 18px;
  border: none;
  text-align: left;
  font-size: 15px;
}
.main.active,
.main:hover {
  background-color: #ddd;
}
div.panel {
  padding: 0 18px;
  background-color: white;
  display: none;
  width: 350px;
}
.active {
  display: block !important;
}
div.panel.show {
  display: block;
}
div.panel.hide {
  display: none;
}
<div class="main">Section 1</div>
<div class="panel active">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<div class="main">Section 2</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<div class="main">Section 3</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

Note: I have taken leisure to updated your code.

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

Comments

1

why don't you just give your first panel class show instead of active? active class seems redundant in your code.

code for the first panel:

<div class="panel show">

Comments

1

After checking if the element in question has a class of active within the loop, try removing the active class on that element if it does. Note, I've added an id to the first panel for this example.

var acc = document.getElementsByClassName("main");
var i;
for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function(){   
      var active = document.getElementById("one").nextElementSibling;
      if(active.classList.contains("active") == true) {
        active.classList.remove("active");
      }
      this.nextElementSibling.classList.toggle("show");   
  }
}
.main {
    background-color: #eee;
    width:350px;
    color: #444;   
    padding: 18px;  
    border: none;
    text-align: left;
    font-size: 15px;

}

.main.active,.main:hover {
    background-color: #ddd;
}

div.panel {
    padding: 0 18px;
   background-color: white;
   display:none;
   width:350px;


}
.active{
    display: block !important;

}

div.panel.show {
    display: block;
}
div.panel.hide {
    display: none;
}
<div id="one" class="main">Section 1</div>
<div class="panel active">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<div class="main">Section 2</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<div class="main">Section 3</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

2 Comments

Note that in the initial run, you have to click twice to get the first panel closed. Not sure if that's the desired effect the OP would like to achieve.
@Wracker Well spotted, thanks - I didn't notice that. I'll revise and see if I can make it better.
1

If you're to use the active class to show the currently opened panel, then you have to also handle it's removal once the user clicks on other panels.

The code below also ensures that there can only be one active panel. All the others will be closed. ( If you don't like the behavior , simply remove the for-loop. )

<!DOCTYPE html>
<html>
<head>
<style>
.main {
    background-color: #eee;
    width:350px;
    color: #444;   
    padding: 18px;  
    border: none;
    text-align: left;
    font-size: 15px;

}

.main.active,.main:hover {
    background-color: #ddd;
}

div.panel {
    padding: 0 18px;
   background-color: white;
   display:none;
   width:350px;


}
.active{
    display: block !important;
}

div.panel.show {
    display: block;
}
div.panel.hide {
    display: none;
}
</style>
</head>
<body>
<div class="main">Section 1</div>
<div class="panel active">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>
<div class="main">Section 2</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<div class="main">Section 3</div>
<div class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

<script>
var acc = document.getElementsByClassName("main");
var i;
for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function(){
		var el_id = this.innerHTML;
		if( ! this.nextElementSibling.classList.contains("active") ){
			this.nextElementSibling.classList.add("active");
			this.nextElementSibling.classList.add("show");
		}else{
			this.nextElementSibling.classList.remove("active");
			this.nextElementSibling.classList.remove("show");
		}

		for( var el = 0; el < acc.length; el++ ){
			if( acc[el].innerHTML != el_id ){
				if(acc[el].nextElementSibling.classList.contains("active")){
					acc[el].nextElementSibling.classList.remove("active");
					acc[el].nextElementSibling.classList.remove("show");
				}
			}
		}
	}
}
</script>

</body>
</html>

Comments

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.