如何使用jQuery实现动态高度Div的切换展开/收起功能
动态高度折叠面板(展开/收起切换修复)
问题分析
原脚本核心问题是未区分展开/收起状态,每次点击都强制计算子元素高度并设置,配合toggle()导致状态逻辑混乱;同时初始HTML中部分容器带内联height样式,干扰状态判断和过渡效果。
修复方案
通过添加状态类标记容器的展开/收起状态,点击时根据当前状态执行对应操作:
- 用
is-open类标记容器展开状态 - 点击触发时:
- 若已展开:设置高度为0,移除
is-open类 - 若未展开:计算子元素总高度并设置,添加
is-open类
- 若已展开:设置高度为0,移除
- 移除初始内联
height样式,统一由脚本控制状态
修复后的完整代码
HTML(移除内联height)
<div class="my_learning_accordion_wrapper"> <div class="learning_accordion"> <div class="learning_accordion_wrap"> <div class="parent_accordion flex-item space-between flex-v-center dark-blue-text"> <div class="title">Completed</div> <i class="fa-light fa-chevron-down"></i> </div> <div class="my_learning_accordion_content dark-blue-text"> <div class="flex-item flex-v-center flex-h-center"> <span>TOTAL:</span> <span class="cme_bold_text"> 10</span> </div> <div class="cme_tracker-parent"> <div class="cme_tracker_wrap flex-item space-between flex-v-center"> <div class="cme_credits"> <span class="cme_bold_text"></span> <span class="credits_text font-weight-400">CE credits</span> </div> <div class="cme_activity_title_wrap"> <div class="activity_type light-blue-text">touchTALKS</div> <div class="activity_title font-weight-400">test 3</div> </div> </div> </div> </div> </div> <div class="learning_accordion_wrap"> <div class="parent_accordion flex-item space-between flex-v-center dark-blue-text"> <div class="title">In Progress</div> <i class="fa-light fa-chevron-down rotate"></i> </div> <div class="my_learning_accordion_content dark-blue-text is-open"> <div class="cme_tracker-parent"> <div> <div class="cme_tracker_wrap flex-item space-between flex-v-center"> <div class="cme_credits grey-text"> <span class="cme_bold_text"></span> <span class="credits_text font-weight-400">CE credits</span> </div> <div class="cme_activity_title_wrap"> <div class="activity_type light-blue-text">touchEXPERT OPINIONS</div> <div class="activity_title font-weight-400">Chronic kidney disease in patients with type 2 diabetes</div> </div> </div> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#"> Continue and complete test to claim credits </a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> </div> </div> <div class="cme_tracker-parent"> <div> <div class="cme_tracker_wrap flex-item space-between flex-v-center"> <div class="cme_credits grey-text"> <span class="cme_bold_text">1.5</span> <span class="credits_text font-weight-400">CE credits</span> </div> <div class="cme_activity_title_wrap"> <div class="activity_type light-blue-text">touchIN CONVERSATION</div> <div class="activity_title font-weight-400">Achieving individualized glycemic targets in patients with type 2 diabetes</div> </div> </div> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#"> Continue and complete test to claim credits </a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> </div> </div> </div> <div class="recommendations_and_user_settings"> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#">Saved activities</a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#">Your learning history</a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#">Clinical Interests</a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#">Communication Preferences</a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#">Notifications</a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> <div class="child_page_links flex-item space-between flex-v-center"> <a class="user_setting_links light-blue-text" href="#">Account settings</a> <i class="fa-light fa-arrow-right-long light-blue-text"></i> </div> </div> </div> </div> </div>
jQuery脚本
$(".parent_accordion").click(function() { const $trigger = $(this); const $content = $trigger.next(".my_learning_accordion_content"); const $icon = $trigger.find("i"); // 判断当前展开状态 if ($content.hasClass("is-open")) { // 收起逻辑 $content.css("height", "0").removeClass("is-open"); } else { // 展开逻辑:计算子元素总高度(包含margin) let totalHeight = 0; $content.children().each(function() { totalHeight += $(this).outerHeight(true); }); $content.css("height", totalHeight + "px").addClass("is-open"); } // 切换箭头旋转状态 $icon.toggleClass("rotate"); }); // 页面加载时初始化默认展开容器的高度 $(".my_learning_accordion_content.is-open").each(function() { let totalHeight = 0; $(this).children().each(function() { totalHeight += $(this).outerHeight(true); }); $(this).css("height", totalHeight + "px"); });
CSS(补充箭头旋转动画)
.my_learning_accordion_content { height: 0; overflow: hidden; transition: height 0.5s ease; } /* 箭头旋转过渡动画 */ .fa-chevron-down.rotate { transform: rotate(180deg); transition: transform 0.3s ease; }
关键优化点
- 用
is-open类明确标记状态,避免逻辑混乱 - 采用
outerHeight(true)计算高度,包含元素margin,适配更复杂布局 - 页面加载时自动初始化默认展开容器的高度
- 移除内联样式,实现样式与逻辑分离
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

