Hii all 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. Please help. Any help is apprecated
<!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>
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">
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>
</div>
You can try something like this:
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.
</div>
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>
</div>