I have created this toggle script which works well but I need to improve it so that onclick, any previously collapsed (i.e. open) subcats would simultaneously close and only the one clicked should collapse (i.e. open).
var collapse = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < collapse.length; i ) {
collapse[i].addEventListener("click", function() {
this.classList.toggle("activeCollapse");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight "px";
}
});
}
.catColumn {
width: 400px;
margin: 0 auto;
}
.collapsible {
width: 100%;
padding: 14px 8px;
margin-top: 10px;
color: #5a2e0f;
background-color: #fff;
border: 1px solid #c1bfbf;
outline: none;
border-radius: 6px;
}
.collapsible:hover {
background-color: #efdac6;
}
.collapsible:after {
float: right;
content: '\002B';
color: #5a2e0f;
font-size: 1.8em;
margin-left: 5px;
cursor: pointer;
line-height: 26px;
}
.activeCollapse {
background-color: #efdac6;
border-radius: 0;
border-bottom: 0px;
}
.activeCollapse:after {
content: "\2212";
}
/**/
ul.subcats {
width: 100%;
max-height: 0;
transition: max-height 1s ease-out;
overflow: hidden;
font-size: 13px;
}
ul.subcats li {
padding: 12px;
}
<div >
<div >cat1</div>
<ul >
<li>subcat1</li>
<li>subcat2</li>
</ul>
<div >cat2</div>
<ul >
<li>subcat3</li>
<li>subcat4</li>
</ul>
</div>
CodePudding user response:
var collapse = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < collapse.length; i ) {
collapse[i].addEventListener("click", function() {
this.classList.toggle("activeCollapse");
for (j = 0; j < collapse.length; j ) {
this.classList.remove("activeCollapse");
if(j!=i)
collapse[j].nextElementSibling.style.maxHeight = null;
var content = this.nextElementSibling;
}
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight "px";
}
});
}
.catColumn {
width: 400px;
margin: 0 auto;
}
.collapsible {
width: 100%;
padding: 14px 8px;
margin-top: 10px;
color: #5a2e0f;
background-color: #fff;
border: 1px solid #c1bfbf;
outline: none;
border-radius: 6px;
}
.collapsible:hover {
background-color: #efdac6;
}
.collapsible:after {
float: right;
content: '\002B';
color: #5a2e0f;
font-size: 1.8em;
margin-left: 5px;
cursor: pointer;
line-height: 26px;
}
.activeCollapse {
background-color: #efdac6;
border-radius: 0;
border-bottom: 0px;
}
.activeCollapse:after {
content: "\2212";
}
/**/
ul.subcats {
width: 100%;
max-height: 0;
transition: max-height 1s ease-out;
overflow: hidden;
font-size: 13px;
}
ul.subcats li {
padding: 12px;
}
<div >
<div >cat1</div>
<ul >
<li>subcat1</li>
<li>subcat2</li>
</ul>
<div >cat2</div>
<ul >
<li>subcat3</li>
<li>subcat4</li>
</ul>
</div>
CodePudding user response:
First, loop through the open elements and remove the class and set max height to null. Then do your normal code.
I also changed your event Listener so you only have one instead of one for each element.
var collapse = document.querySelector(".catColumn");
collapse.addEventListener("click",function(e){
let el = e.target;
if(el.className.indexOf("collapsible") > -1){
let shown = document.querySelectorAll(".activeCollapse");
shown.forEach(function(activeEl){
activeEl.classList.remove("activeCollapse");
activeEl.nextElementSibling.style.maxHeight = null;
});
el.classList.toggle("activeCollapse");
var content = el.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight "px";
}
}
});
.catColumn {
width: 400px;
margin: 0 auto;
}
.collapsible {
width: 100%;
padding: 14px 8px;
margin-top: 10px;
color: #5a2e0f;
background-color: #fff;
border: 1px solid #c1bfbf;
outline: none;
border-radius: 6px;
}
.collapsible:hover {
background-color: #efdac6;
}
.collapsible:after {
float: right;
content: '\002B';
color: #5a2e0f;
font-size: 1.8em;
margin-left: 5px;
cursor: pointer;
line-height: 26px;
}
.activeCollapse {
background-color: #efdac6;
border-radius: 0;
border-bottom: 0px;
}
.activeCollapse:after {
content: "\2212";
}
/**/
ul.subcats {
width: 100%;
max-height: 0;
transition: max-height 1s ease-out;
overflow: hidden;
font-size: 13px;
}
ul.subcats li {
padding: 12px;
}
<div >
<div >cat1</div>
<ul >
<li>subcat1</li>
<li>subcat2</li>
</ul>
<div >cat2</div>
<ul >
<li>subcat3</li>
<li>subcat4</li>
</ul>
</div>
CodePudding user response:
var parentDiv = document.getElementsByClassName("catColumn")[0];
parentDiv.addEventListener("click",function(e){
let current= e.target;
var collapse = document.getElementsByClassName("collapsible");
let toExpand = !current.nextElementSibling.style.maxHeight ;
for (let i = 0; i < collapse.length; i ) {
var content = collapse[i].nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
collapse[i].classList.toggle("activeCollapse");
}
}
let toToggle = current.nextElementSibling;
if(toExpand ){
toToggle.style.maxHeight = content.scrollHeight "px";
current.classList.toggle("activeCollapse");
}
});
.catColumn {
width: 400px;
margin: 0 auto;
}
.collapsible {
width: 100%;
padding: 14px 8px;
margin-top: 10px;
color: #5a2e0f;
background-color: #fff;
border: 1px solid #c1bfbf;
outline: none;
border-radius: 6px;
}
.collapsible:hover {
background-color: #efdac6;
}
.collapsible:after {
float: right;
content: '\002B';
color: #5a2e0f;
font-size: 1.8em;
margin-left: 5px;
cursor: pointer;
line-height: 26px;
}
.activeCollapse {
background-color: #efdac6;
border-radius: 0;
border-bottom: 0px;
}
.activeCollapse:after {
content: "\2212";
}
/**/
ul.subcats {
width: 100%;
max-height: 0;
transition: max-height 1s ease-out;
overflow: hidden;
font-size: 13px;
}
ul.subcats li {
padding: 12px;
}
<div >
<div >cat1</div>
<ul >
<li>subcat1</li>
<li>subcat2</li>
</ul>
<div >cat2</div>
<ul >
<li>subcat3</li>
<li>subcat4</li>
</ul>
</div>