Reputation: 9
Here is my code and the JSfiddle code, I am having an issue now that if one is opened and you try to close it again it won't close.
https://jsfiddle.net/k68z3aLv/
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
var b;
for(b = 0; b < coll.length; b++) {
if(coll[b] != coll[i]) {
if(coll[b].getAttribute('id') == 'submenuopened')
{
coll[b].classList.remove("active");
coll[b].setAttribute("id",'');
var content3 = coll[b].nextElementSibling;
content3.style.display = "none";
// sleep(0);
}
}
}
this.classList.toggle("active");
if(this.getAttribute('id') == 'submenuopened') {
this.setAttribute("id",'ha');
} else { this.setAttribute("id", "submenuopened"); }
var content = this.nextElementSibling;
if (content.style.display == 'block'){
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active, .collapsible:hover {
background-color: #555;
}
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
<button type="button" class="collapsible">Open Section 1</button>
<div class="content">
<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>
<button type="button" class="collapsible">Open Section 2</button>
<div class="content">
<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>
<button type="button" class="collapsible">Open Section 3</button>
<div class="content">
<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>
Upvotes: 0
Views: 69
Reputation: 1234
I little bit optimized your code jsfiddle, id
was removed because active
class is enough, open/close moved to CSS because it's a better way to do it, extra code was removed to look it more clear
var coll = document.getElementsByClassName("collapsible");
for (let i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
for(let n = 0; n < coll.length; n++) {
if(coll[n] == this) continue;
coll[n].classList.remove("active");
}
this.classList.toggle("active");
});
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active, .collapsible:hover {
background-color: #555;
}
.collapsible.active + .content {
display: block;
}
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
<button type="button" class="collapsible">Open Section 1</button>
<div class="content">
<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>
<button type="button" class="collapsible">Open Section 2</button>
<div class="content">
<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>
<button type="button" class="collapsible">Open Section 3</button>
<div class="content">
<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>
Upvotes: 1
Reputation: 5840
There is actually a much simpler way to iterate through your DOM elements and also to make your code more understandable.
These are the edits required. HTML and CSS are very small adjustments, the JS part is the interesting one.
<div class="collapsible">
<header>
Open Section 1
</header>
<div class="content">
<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>
...
Unless your buttons to open and close the collapsibles are far away from the actual content (which is not the case you mentioned here), semantically it's good for the whole element to be grouped together.
.collapsible header {
...
}
.collapsible.is-active .content {
display: block;
}
The only change required here is adjusting the CSS to target the header
element, as the .collapsible
class is now applied to the parent.
Also, we add a simple semantic class that will tell us which one is currently active, and show it.
const collapsibles = Array.from(document.getElementsByClassName("collapsible"));
function toggleVisibility(e) {
const parent = e.target.parentElement;
parent.classList.toggle("is-active");
collapsibles.forEach(collapsible => {
if(collapsible === parent) return;
collapsible.classList.remove("is-active")
});
}
collapsibles.forEach(collapsible => {
collapsible.querySelector("header").addEventListener("click", toggleVisibility);
});
for
loops.toggle
the current active one if you click on itself, and close all the rest.Upvotes: 1
Reputation: 20434
Your code was quite confusing for me to decipher, so I just re-wrote it in what I would consider a clear way. This was achieved by creating two functions to open or close the submenu for a particular element.
var buttoncolumn = document.getElementsByClassName('collapsible');
function closesubmenu(el) {
el.setAttribute('id', '');
el.classList.remove('active');
el.nextElementSibling.style.display = 'none';
}
function opensubmenu(el) {
el.setAttribute('id', 'submenuopened');
el.classList.add('active');
el.nextElementSibling.style.display = 'block';
}
for (let button of buttoncolumn) {
button.addEventListener('click', function() {
if (this.getAttribute('id') == 'submenuopened') {
closesubmenu(this);
} else {
for (let other of buttoncolumn) {
closesubmenu(other);
}
opensubmenu(this);
}
});
};
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active,
.collapsible:hover {
background-color: #555;
}
.content {
padding: 0 18px;
display: none;
overflow: hidden;
background-color: #f1f1f1;
}
<button type="button" class="collapsible">Open Section 1</button>
<div class="content">
<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>
<button type="button" class="collapsible">Open Section 2</button>
<div class="content">
<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>
<button type="button" class="collapsible">Open Section 3</button>
<div class="content">
<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>
Upvotes: 0