JS设置元素height为scrollHeight后无法重置为0及修改非内联height问题
问题排查与解决方案
一、height无法重置为0的根因
- 全局状态冲突:你定义了全局的
isClosed变量控制所有折叠框的状态,多个元素点击时状态会互相干扰,逻辑判断会出现错乱。 - display属性阻断效果:
.h-strench-content默认设置了display:none,当你移除h-strench-box-out类时,元素会先切换为display:none,此时即便执行了height:0的赋值,也看不到对应的效果,同时CSS过渡对display:none的元素完全不生效。 - 样式优先级问题:通过
element.style设置的内联样式优先级远高于CSS类中定义的样式,你之前设置的height内联值,不会被类中的height:0覆盖,必须手动修改或清空内联样式才能生效。
二、修复方案
第一步:调整CSS,移除display控制
不用display:none控制隐藏,改为通过height:0 + overflow:hidden实现隐藏,保证过渡效果能正常触发:
.h-strench-content { height: 0; padding: 0; overflow: hidden; transition: height 0.4s ease-in; } /* 删除原有的.h-strench-box-out .h-strench-content的display:block规则 */ .h-strench-btn { transition: transform 0.3s ease-out; } .h-strench-btn::before { content: '\f13a'; font-family: "Font Awesome 5 Free"; font-size: 27px; font-weight: 600; }
第二步:优化JS逻辑,移除全局状态
直接通过元素的类名判断展开/收起状态,避免全局变量冲突:
const cals = document.getElementsByClassName('h-strench-box'); for (let i = 0; i < cals.length; i ++) { cals[i].addEventListener('click', function(e) { const content = this.querySelector('.h-strench-content'); const isCurrentOpen = this.classList.contains('h-strench-box-out'); // 先统一收起所有折叠框 for (let j = 0; j < cals.length; j ++) { cals[j].classList.remove('h-strench-box-out'); cals[j].querySelector('.h-strench-content').style.height = '0'; } // 如果当前点击的是关闭状态,就展开 if (!isCurrentOpen) { this.classList.add('h-strench-box-out'); content.style.height = content.scrollHeight + 'px'; } }); }
三、修改非内联height值的方案
如果不想通过element.style直接修改内联height属性,推荐使用CSS变量+类切换的方案,所有height的赋值逻辑都在CSS类中实现,JS只负责传递动态高度参数:
- 调整CSS规则:
.h-strench-content { height: 0; padding: 0; overflow: hidden; transition: height 0.4s ease-in; } /* 用CSS变量定义展开时的高度 */ .h-strench-box-out .h-strench-content { height: var(--content-height); }
- 修改JS代码,仅设置CSS变量,不直接修改height内联属性:
// 把原来的content.style.height赋值替换为下面的代码 content.style.setProperty('--content-height', content.scrollHeight + 'px');
这种方案下,height属性的取值是由CSS类控制的,不属于内联样式修改,完全符合你的需求。
内容的提问来源于stack exchange,提问作者hayley
相关产品推荐
相关产品推荐

