点击浏览器后退/前进按钮时隐藏Spinner加载动画的问题求助
问题解决:浏览器后退/前进时自动隐藏CSS Spinner
问题分析
点击外部链接时触发Spinner动画,但通过浏览器后退/前进返回页面后,Spinner仍显示。本地环境正常但部署后异常,核心原因:
- jQuery版本:每次点击链接都会创建新的
loadingDiv,监听popstate时又创建新元素执行hide(),根本没操作到之前显示的Spinner; - 原生JS版本:仅在点击时添加
loading类,但未处理页面从浏览器缓存(BF Cache)恢复的场景,后退时页面状态被保留; popstate事件并非在所有后退/前进场景下都触发,比如从BF Cache加载页面时不会触发,改用pageshow事件更可靠。
解决方案
方案一:jQuery优化实现
- HTML:提前在页面中添加一个默认隐藏的Spinner容器
<div class="loadingDiv" style="display: none;">loading...</div> <div class="app_link_api_div"> Apps i recently created: <br /> <br /> This API connects to an interactive front-end built with React.js. When pasting a url link of a website, it renders a shortened link --- shareable across various social media websites posts <p>API: <a href="https://example.com/">外部链接示例</a> <br /> <br /></p> </div>
- CSS:保留原样式并补充动画关键帧
.loadingDiv { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; background-color: #f7f9fb89; } .loadingDiv::after { content: ""; width: 60px; height: 60px; border: 15px solid #dddddd; border-top-color: #1ecd97; border-radius: 50%; animation: loading 0.75s ease infinite; } @keyframes loading { from { transform: rotate(0turn); } to { transform: rotate(1turn); } }
- JavaScript/jQuery:复用Spinner元素,监听
pageshow事件确保返回时隐藏
// 仅对外部链接触发Spinner $('a[href^="http"]').on("click", function(){ $('.loadingDiv').show(); }); // 页面显示时(包括后退/前进从缓存加载)隐藏Spinner $(window).on("pageshow", function(){ $('.loadingDiv').hide(); });
方案二:原生JavaScript优化实现
- HTML:添加全局Spinner容器(无需每个链接单独写displayer)
<div class="loading" style="visibility: hidden; opacity: 0;"></div> <div class="app_link_api_div"> Apps i recently created: <br /> <br /> This API connects to an interactive front-end built with React.js. When pasting a url link of a website, it renders a shortened link --- shareable across various social media websites posts <p>API: <a href="https://example.com/">外部链接示例</a> <br /> <br /></p> </div>
- CSS:通过类控制显示状态,保留过渡动画
.loading { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; display: flex; justify-content: center; align-items: center; background-color: #f7f9fb89; transition: opacity 0.75s, visibility 0.75s; } .loading.show { visibility: visible; opacity: 1; } .loading::after { content: ""; width: 60px; height: 60px; border: 15px solid #dddddd; border-top-color: #1ecd97; border-radius: 50%; animation: loading 0.75s ease infinite; } @keyframes loading { from { transform: rotate(0turn); } to { transform: rotate(1turn); } }
- JavaScript:统一控制Spinner,监听
pageshow事件
const spinner = document.querySelector('.loading'); const externalLinks = document.querySelectorAll('a[href^="http"]'); // 点击外部链接显示Spinner externalLinks.forEach(link => { link.addEventListener('click', () => { spinner.classList.add('show'); }); }); // 页面显示时隐藏Spinner window.addEventListener('pageshow', () => { spinner.classList.remove('show'); });
关键说明
- 使用
pageshow而非popstate:该事件在页面加载完成、从BF Cache恢复时都会触发,覆盖所有后退/前进场景; - 复用Spinner元素:避免重复创建DOM,确保操作的是同一个元素;
- 精准匹配外部链接:通过
a[href^="http"]过滤,防止内部导航误触发Spinner。
内容的提问来源于stack exchange,提问作者austinxduong
相关产品推荐
相关产品推荐

