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).
JavaScript
x
13
13
1
var collapse = document.getElementsByClassName("collapsible");
2
var i;
3
for (i = 0; i < collapse.length; i++) {
4
collapse[i].addEventListener("click", function() {
5
this.classList.toggle("activeCollapse");
6
var content = this.nextElementSibling;
7
if (content.style.maxHeight) {
8
content.style.maxHeight = null;
9
} else {
10
content.style.maxHeight = content.scrollHeight + "px";
11
}
12
});
13
}
JavaScript
1
54
54
1
.catColumn {
2
width: 400px;
3
margin: 0 auto;
4
}
5
6
.collapsible {
7
width: 100%;
8
padding: 14px 8px;
9
margin-top: 10px;
10
color: #5a2e0f;
11
background-color: #fff;
12
border: 1px solid #c1bfbf;
13
outline: none;
14
border-radius: 6px;
15
}
16
17
.collapsible:hover {
18
background-color: #efdac6;
19
}
20
21
.collapsible:after {
22
float: right;
23
content: '02B';
24
color: #5a2e0f;
25
font-size: 1.8em;
26
margin-left: 5px;
27
cursor: pointer;
28
line-height: 26px;
29
}
30
31
.activeCollapse {
32
background-color: #efdac6;
33
border-radius: 0;
34
border-bottom: 0px;
35
}
36
37
.activeCollapse:after {
38
content: "2212";
39
}
40
41
42
/**/
43
44
ul.subcats {
45
width: 100%;
46
max-height: 0;
47
transition: max-height 1s ease-out;
48
overflow: hidden;
49
font-size: 13px;
50
}
51
52
ul.subcats li {
53
padding: 12px;
54
}
JavaScript
1
12
12
1
<div class="catColumn">
2
<div class="collapsible">cat1</div>
3
<ul class="subcats">
4
<li>subcat1</li>
5
<li>subcat2</li>
6
</ul>
7
<div class="collapsible">cat2</div>
8
<ul class="subcats">
9
<li>subcat3</li>
10
<li>subcat4</li>
11
</ul>
12
</div>
Advertisement
Answer
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.
JavaScript
1
26
26
1
var collapse = document.querySelector(".catColumn");
2
3
collapse.addEventListener("click", function(e) {
4
let el = e.target;
5
let hideSelf = (el.className.indexOf("activeCollapse") > 0);
6
7
if (el.className.indexOf("collapsible") > -1) {
8
let shown = document.querySelectorAll(".activeCollapse");
9
shown.forEach(function(activeEl) {
10
activeEl.classList.remove("activeCollapse");
11
activeEl.nextElementSibling.style.maxHeight = null;
12
});
13
14
if (hideSelf == false) {
15
el.classList.toggle("activeCollapse");
16
var content = el.nextElementSibling;
17
if (content.style.maxHeight) {
18
content.style.maxHeight = null;
19
} else {
20
content.style.maxHeight = content.scrollHeight + "px";
21
}
22
}
23
24
25
}
26
});
JavaScript
1
54
54
1
.catColumn {
2
width: 400px;
3
margin: 0 auto;
4
}
5
6
.collapsible {
7
width: 100%;
8
padding: 14px 8px;
9
margin-top: 10px;
10
color: #5a2e0f;
11
background-color: #fff;
12
border: 1px solid #c1bfbf;
13
outline: none;
14
border-radius: 6px;
15
}
16
17
.collapsible:hover {
18
background-color: #efdac6;
19
}
20
21
.collapsible:after {
22
float: right;
23
content: '02B';
24
color: #5a2e0f;
25
font-size: 1.8em;
26
margin-left: 5px;
27
cursor: pointer;
28
line-height: 26px;
29
}
30
31
.activeCollapse {
32
background-color: #efdac6;
33
border-radius: 0;
34
border-bottom: 0px;
35
}
36
37
.activeCollapse:after {
38
content: "2212";
39
}
40
41
42
/**/
43
44
ul.subcats {
45
width: 100%;
46
max-height: 0;
47
transition: max-height 1s ease-out;
48
overflow: hidden;
49
font-size: 13px;
50
}
51
52
ul.subcats li {
53
padding: 12px;
54
}
JavaScript
1
12
12
1
<div class="catColumn">
2
<div class="collapsible">cat1</div>
3
<ul class="subcats">
4
<li>subcat1</li>
5
<li>subcat2</li>
6
</ul>
7
<div class="collapsible">cat2</div>
8
<ul class="subcats">
9
<li>subcat3</li>
10
<li>subcat4</li>
11
</ul>
12
</div>