点击后退/前进按钮时load事件未触发,加载器持续显示如何解决?
解决后退/前进按钮加载器持续显示的问题
问题根源
你的问题核心是**浏览器BF Cache(往返缓存)**的影响:部分浏览器在用户点击后退/前进时,会直接从缓存恢复页面,不会触发load事件;同时原代码里的isValid函数逻辑完全错误(参数传的是cancelable,但函数内部判断的却是formElement是否为null),再加上beforeunload在缓存场景下的行为不一致,最终导致加载器无法正常隐藏。
修复方案
改用pageshow和pagehide事件适配缓存场景,同时修正逻辑错误,以下是完整代码:
document.addEventListener("DOMContentLoaded", function () { const loaderWrapper = document.querySelector(".loader-wrapper"); function showLoader() { loaderWrapper.classList.remove("hidden"); } function hideLoader() { loaderWrapper.classList.add("hidden"); } // 修正isValid函数:校验加载器元素是否存在,避免空指针 function isValid(element) { return element !== null; } // 初始加载显示加载器 if (isValid(loaderWrapper)) { showLoader(); } // 页面完全加载(含资源)后隐藏加载器 window.addEventListener("load", hideLoader); // 页面即将被隐藏(进入缓存、关闭标签、导航离开)时显示加载器 window.addEventListener("pagehide", function () { if (isValid(loaderWrapper)) { showLoader(); } }); // 页面从缓存/重新加载显示时,强制隐藏加载器 window.addEventListener("pageshow", function () { if (isValid(loaderWrapper)) { hideLoader(); } }); // 处理手动修改历史记录的popstate场景 window.addEventListener("popstate", function () { if (isValid(loaderWrapper)) { showLoader(); // 页面已完成状态切换,短延迟后隐藏加载器 setTimeout(hideLoader, 100); } }); });
关键调整说明
- 替换beforeunload为pagehide:
pagehide在页面进入缓存、关闭、导航离开时都会触发,比beforeunload更适配缓存场景。 - 新增pageshow监听:无论页面是重新加载还是从缓存恢复,
pageshow都会触发,确保加载器能被及时隐藏。 - 修正isValid函数:现在用于校验加载器元素是否存在,避免因元素找不到导致的报错。
- 优化popstate处理:手动处理历史记录切换场景,保证加载器的显示/隐藏逻辑闭环。
额外建议
- 不要在
beforeunload中用setTimeout:页面卸载时定时器执行时机不可控,容易导致逻辑失效。 - 测试缓存场景:在Chrome DevTools的Network面板中,取消勾选"Disable cache",模拟真实用户的缓存导航行为。
- 加载器样式优化:给
hidden类添加display: none或visibility: hidden配合过渡动画,提升用户体验。
内容的提问来源于stack exchange,提问作者Dinesh Uprety
相关产品推荐
相关产品推荐

