为何JavaScript折叠面板的全部展开/收起按钮在IE中失效?
解决IE中折叠面板「全部展开/全部收起」按钮失效的问题
看起来你遇到的核心问题是IE浏览器不支持NodeList的forEach方法——你的showexplanation和hideAll函数里用到了document.querySelectorAll().forEach(),但IE(尤其是IE11及更早版本)的NodeList对象没有内置这个方法,导致按钮点击后代码执行中断,功能直接失效。
下面是完全基于你现有JS/HTML/CSS技术栈的兼容修复方案:
修改后的完整代码
JavaScript
var coll = document.getElementsByClassName("accordion"); var i; for (i = 0; i < coll.length; i++) { coll[i].addEventListener("click", function() { var content = this.nextElementSibling; if (content.style.display === "table-row") { content.style.display = "none"; this.firstElementChild.firstChild.style.transform = "rotate(-45deg)"; } else { content.style.display = "table-row"; this.firstElementChild.firstChild.style.transform = "rotate(45deg)"; } }); } function showexplanation() { // 替换forEach为传统for循环,适配IE var contents = document.querySelectorAll('.accordion-content'); for(var j = 0; j < contents.length; j++){ contents[j].style.display = "table-row"; } var arrows = document.querySelectorAll('.arrow-right'); for(var k = 0; k < arrows.length; k++){ arrows[k].style.transform = "rotate(45deg)"; } } function hideAll() { // 同样替换forEach为for循环 var contents = document.querySelectorAll('.accordion-content'); for(var j = 0; j < contents.length; j++){ contents[j].style.display = "none"; } var arrows = document.querySelectorAll('.arrow-right'); for(var k = 0; k < arrows.length; k++){ arrows[k].style.transform = "rotate(-45deg)"; } }
CSS(无需修改,保留原代码即可)
.accordion { background-color: #777; color: white; cursor: pointer; padding: 10px; width: 100%; border: none; text-align: left; outline: none; font-size: 15px; } .accordion td { padding: 15px; } .accordion td:nth-child(1) { min-width: 40px; text-align: center; } .accordion td:nth-child(2) { padding-left: 0px; } .accordion-content { padding: 25px; overflow: hidden; background-color: #f1f1f1; display: none; } .accordion-content td { padding: 15px; } .arrow-right { border: solid white; border-width: 0 1.5px 1.5px 0; display: inline-block; padding: 3px; transform: rotate(-45deg); transition: all 200ms ease 0s; }
HTML(无需修改,保留原代码即可)
<table style="max-width: 700px;" border="0" cellspacing="0"> <tbody> <tr class="accordion"> <td style="width: 1%"><i class="arrow-right"></i></td> <td>Item 1</td> <td style="text-align: right;">£1,800</td> </tr> <tr class="accordion-content"> <td colspan="3"> <p>Explanation 1</p> </td> </tr> <tr class="accordion"> <td style="width: 1%"><i class="arrow-right"></i></td> <td>Item 3</td> <td style="text-align: right;">£1,750</td> </tr> <tr class="accordion-content"> <td colspan="3"> <p>Explanation 3</p> </td> </tr> <tr class="accordion"> <td style="width: 1%"><i class="arrow-right"></i></td> <td>Item 3</td> <td style="text-align: right;">£1,750</td> </tr> <tr class="accordion-content"> <td colspan="3"> <p>Explanation 3</p> </td> </tr> </tbody> </table> <p style="margin-top: 20px;"> <button onclick="showexplanation()">Show all</button> </p> <p style="margin-top: 20px;" id="solution"> <button onclick="hideAll()">Hide all</button> </p>
核心修复说明
- 替换
forEach为传统for循环:这是解决IE兼容的关键,因为IE不支持NodeList对象的forEach方法,改用for循环遍历querySelectorAll返回的结果,就能保证代码在IE中正常执行。 - 保留原有单个折叠逻辑:你原有的单个面板折叠功能在多数浏览器正常,且
getElementsByClassName和addEventListener在IE9+是支持的,所以不需要修改这部分代码。
可选的老版本IE兼容(如IE8)
如果需要支持更老的IE版本,还需要补充两个调整:
- 将
addEventListener替换为attachEvent('onclick', 函数) - 将
nextElementSibling替换为过滤文本节点的nextSibling:var content = this.nextSibling; while (content && content.nodeType !== 1) { content = content.nextSibling; }
测试修改后的代码,IE里的「全部展开/全部收起」按钮应该就能正常工作了,同时完全兼容现代浏览器。
内容的提问来源于stack exchange,提问作者novice
相关产品推荐
相关产品推荐

