You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止浏览器后退时onbeforeunload事件触发加载模态框弹出?

问题根因

  1. 你注册的定时器属于页面全局上下文,当页面被推入浏览器**往返缓存(Back/Forward Cache,简称bfcache)**时(用户点击后退就会触发该缓存逻辑,页面不会真的销毁),之前设置的2秒定时器并不会被自动清除,页面从缓存恢复后定时器到期就会执行showLoader弹出模态框。
  2. 原逻辑没有判断导航来源,后退恢复的页面会直接执行加载框显示逻辑。

修改后完整代码

// 全局存储定时器ID,方便后续清除
let unloadTimer = null;

window.onbeforeunload = function () {
    unloadTimer = window.setTimeout(showLoader, 2000);
}

// 监听pageshow事件,页面从缓存恢复时触发
window.addEventListener('pageshow', function(e) {
    // 页面从bfcache恢复时,清除定时器+销毁可能存在的模态框
    if (e.persisted) {
        if (unloadTimer) {
            clearTimeout(unloadTimer);
            unloadTimer = null;
        }
        const loadModal = document.getElementById('layoutLoadingModal');
        if (loadModal) loadModal.remove();
    }
});

// 监听pagehide事件,页面即将被缓存/销毁时先清除定时器
window.addEventListener('pagehide', function() {
    if (unloadTimer) {
        clearTimeout(unloadTimer);
        unloadTimer = null;
    }
});

function showLoader() {
    // 增加导航类型判断,后退/前进场景下不弹出加载框
    const navEntry = performance.getEntriesByType('navigation')[0];
    if (navEntry && navEntry.type === 'back_forward') return;

    var loader = '<div id="layoutLoadingModal" class="modal fade" role="dialog">' +
        '<div class="modal-dialog">' +
            '<div class="modal-content">' +
                '<div class="modal-body">' +
                    '<h1>Loading!</h1>' +
                '</div>' +
            '</div>' +
        '</div>' +
    '</div>';
    $("body").append(loader);
    $('#layoutLoadingModal').modal('show');
}

核心改动说明

  • 全局存储定时器ID,在pagehide(页面即将被缓存/销毁)和pageshow(页面从缓存恢复)两个节点清除定时器,从根源避免缓存页面的定时器到期触发逻辑。
  • 利用Performance API判断当前导航类型,如果是后退/前进触发的页面加载,直接跳过加载框的显示逻辑。
  • 页面从bfcache恢复时自动检测并移除已存在的加载模态框,避免残留。

内容的提问来源于stack exchange,提问作者Fredrik Kindahl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 04:36:03