求助:如何让W3Schools折叠组件同一时间仅一个展开?
Hey there! Let's fix this collapsible panel issue step by step—since you're just starting out with JavaScript, this is a super common gotcha and easy to tweak.
The Root of the Problem
Your original code toggles the clicked panel's state, but it doesn't handle closing other panels when a new one is opened. That's why all panels expand at once when you click any of them.
Solution 1: Only One Panel Open Globally
If you want all panels to behave like a single group (only one open at a time), modify your JS to first close every other panel before toggling the clicked one:
var coll = document.getElementsByClassName("collapsible"); var i; for (i = 0; i < coll.length; i++) { coll[i].addEventListener("click", function() { // Step 1: Close all other collapsible panels var allPanels = document.getElementsByClassName("collapsible"); for (var j = 0; j < allPanels.length; j++) { if (allPanels[j] !== this) { allPanels[j].classList.remove("active"); var otherContent = allPanels[j].nextElementSibling; otherContent.style.maxHeight = null; } } // Step 2: Toggle the clicked panel's state this.classList.toggle("active"); var content = this.nextElementSibling; if (content.style.maxHeight) { content.style.maxHeight = null; } else { content.style.maxHeight = content.scrollHeight + "px"; } }); }
How This Works:
When you click a panel, we first loop through every collapsible element. For each one that isn't the clicked panel, we remove its active class and collapse its content. Then we toggle the clicked panel as usual.
Solution 2: Only One Panel Open Per Row
Since your layout is responsive (4 columns desktop, 2 columns mobile), you might want panels to behave independently per row. Here's how to do that (assuming your rows have a class like .row—adjust this to match your actual HTML structure):
var coll = document.getElementsByClassName("collapsible"); var i; for (i = 0; i < coll.length; i++) { coll[i].addEventListener("click", function() { // Step 1: Find the row containing the clicked panel var currentRow = this.closest('.row'); // Replace .row with your actual row container class // Step 2: Close only the panels in the same row var rowPanels = currentRow.getElementsByClassName("collapsible"); for (var j = 0; j < rowPanels.length; j++) { if (rowPanels[j] !== this) { rowPanels[j].classList.remove("active"); var otherContent = rowPanels[j].nextElementSibling; otherContent.style.maxHeight = null; } } // Step 3: Toggle the clicked panel's state this.classList.toggle("active"); var content = this.nextElementSibling; if (content.style.maxHeight) { content.style.maxHeight = null; } else { content.style.maxHeight = content.scrollHeight + "px"; } }); }
Key Note:
If your rows don't use a .row class, update this.closest('.row') to match your actual row container selector (e.g., .grid-row). The closest() method finds the nearest parent element with that class, which works perfectly for responsive rows.
Quick Tip for New Developers
You don't need to duplicate your CSS/JS into collapsible2 classes—this single modified script will handle all your panels cleanly. Keeping code DRY (Don't Repeat Yourself) makes it easier to maintain later!
内容的提问来源于stack exchange,提问作者Sean Porter

