Creé este script de alternancia que funciona bien, pero necesito mejorarlo para que, al hacer clic, cualquier subgato previamente colapsado (es decir, abierto) se cierre simultáneamente y solo el que se hizo clic debe colapsar (es decir, abrir).
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 class="catColumn"> <div class="collapsible">cat1</div> <ul class="subcats"> <li>subcat1</li> <li>subcat2</li> </ul> <div class="collapsible">cat2</div> <ul class="subcats"> <li>subcat3</li> <li>subcat4</li> </ul> </div> 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 class="catColumn"> <div class="collapsible">cat1</div> <ul class="subcats"> <li>subcat1</li> <li>subcat2</li> </ul> <div class="collapsible">cat2</div> <ul class="subcats"> <li>subcat3</li> <li>subcat4</li> </ul> </div>Primero, recorra los elementos abiertos y elimine la clase y establezca la altura máxima en nulo. Luego haz tu código normal.
También cambié su detector de eventos para que solo tenga uno en lugar de uno para cada elemento.
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 class="catColumn"> <div class="collapsible">cat1</div> <ul class="subcats"> <li>subcat1</li> <li>subcat2</li> </ul> <div class="collapsible">cat2</div> <ul class="subcats"> <li>subcat3</li> <li>subcat4</li> </ul> </div> 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 class="catColumn"> <div class="collapsible">cat1</div> <ul class="subcats"> <li>subcat1</li> <li>subcat2</li> </ul> <div class="collapsible">cat2</div> <ul class="subcats"> <li>subcat3</li> <li>subcat4</li> </ul> </div>