如何阻止Bootstrap Collapse在页面刷新时重新执行动画?
解决Bootstrap Collapse刷新时的展开/收起动画问题
问题分析
页面刷新时,Bootstrap Collapse组件默认会从折叠状态初始化,即便通过Cookie恢复展开状态,JS触发展开的过程仍会执行过渡动画,导致视觉闪烁。另外你的代码存在重复ID(两个面板都用#ui-basic),这会直接导致Collapse功能异常,必须先修正。
解决方案
通过以下步骤彻底解决动画问题:
- 修正重复ID:给每个折叠面板设置唯一ID,避免功能冲突
- 预设置初始状态:页面加载时直接从Cookie读取状态,给目标面板添加
show类,同时临时禁用过渡动画 - 恢复动画:Collapse组件初始化完成后,移除禁用动画的临时类,确保后续交互正常触发动画
- 同步状态到Cookie:监听折叠/展开事件,实时更新Cookie中的状态
代码实现
修正后的HTML
<li class="nav-item"> <a class="nav-link" data-bs-toggle="collapse" data-bs-target="#listing-management-1" aria-expanded="true" aria-controls="listing-management-1"> <i class="icon-layout menu-icon"></i> <span class="menu-title">Listing Management</span> <i class="menu-arrow"></i> </a> <div class="collapse" id="listing-management-1"> <ul class="nav flex-column sub-menu sideBarPanel"> <li class="nav-item"> <a class="nav-link" href="/someURL">Create</a></li> <li class="nav-item"> <a class="nav-link" href="/someURL">Featured List</a></li> <li class="nav-item"> <a class="nav-link" href="/someURL">Automated List</a></li> </ul> </div> </li> <li class="nav-item"> <a class="nav-link" data-bs-toggle="collapse" data-bs-target="#listing-management-2" aria-expanded="true" aria-controls="listing-management-2"> <i class="icon-layout menu-icon"></i> <span class="menu-title">Listing Management</span> <i class="menu-arrow"></i> </a> <div class="collapse" id="listing-management-2"> <ul class="nav flex-column sub-menu sideBarPanel"> <li class="nav-item"> <a class="nav-link" href="/someURL">Option 4</a></li> <li class="nav-item"> <a class="nav-link" href="/someURL">Option 5</a></li> <li class="nav-item"> <a class="nav-link" href="/someURL">Option 6</a></li> </ul> </div> </li>
对应的JavaScript
// 读取Cookie function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); } // 设置Cookie function setCookie(name, value, days = 7) { const date = new Date(); date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); const expires = `expires=${date.toUTCString()}`; document.cookie = `${name}=${value}; ${expires}; path=/`; } // 页面加载逻辑 document.addEventListener('DOMContentLoaded', function() { const collapseIds = ['listing-management-1', 'listing-management-2']; // 恢复状态并禁用初始动画 collapseIds.forEach(id => { const collapseEl = document.getElementById(id); if (!collapseEl) return; const isExpanded = getCookie(`collapse_${id}`) === 'true'; if (isExpanded) { collapseEl.classList.add('show', 'no-transition'); const triggerEl = document.querySelector(`[data-bs-target="#${id}"]`); if (triggerEl) triggerEl.setAttribute('aria-expanded', 'true'); } }); // 初始化Collapse组件 document.querySelectorAll('.collapse').forEach(el => new bootstrap.Collapse(el)); // 初始化完成后恢复动画 setTimeout(() => { document.querySelectorAll('.no-transition').forEach(el => el.classList.remove('no-transition')); }, 10); // 同步状态到Cookie document.addEventListener('shown.bs.collapse', e => setCookie(`collapse_${e.target.id}`, 'true')); document.addEventListener('hidden.bs.collapse', e => setCookie(`collapse_${e.target.id}`, 'false')); });
必要的CSS
.no-transition { transition: none !important; }
原理说明
- 页面加载时直接通过HTML类设置展开状态,避免JS触发的动画
- 临时添加
no-transition类覆盖Bootstrap默认过渡样式,确保初始化时无动画 - 组件初始化完成后移除临时类,不影响后续用户交互的正常动画
- 实时同步折叠状态到Cookie,确保刷新后能准确恢复
内容的提问来源于stack exchange,提问作者user2300947
相关产品推荐
相关产品推荐

