首页 > 解决方案 > 浏览器后退按钮在 Safari 和 Chrome 中以不同方式处理脚本更改

问题描述

对于耗时的导航(在 Python/Flask 后端实现),最好有视觉反馈,指示下一页预计需要一些时间来加载,即使它只是快速的 DIY devops 脚本。为了以很少的技术开销实现这一点,我实现了一个加载消息,如下所示:

<script type="text/javascript">
    function loading(){
        document.getElementById("loading").style.display = 'block';
        document.getElementById("content").style.display = 'none';
    }
</script>

<body>
    <div id="loading" class="invisible"> <!-- display: none; -->
        Loading ...
    </div>
    <div id="content">
        <a href="/time/consuming/service/call" onclick="loading();">Work miracles.</a>

(感谢另一个 SO 问题中的一些答案 ......)

在所有浏览器中都可以进行向前导航,但是在(当前)Safari 或 Firefox 中使用目标页面的浏览器后退按钮时,我最终会得到“正在加载...”,因为在display: none;重新加载页面时会保留从浏览器缓存中。在 Chrome 中,浏览器后退按钮适用于这种情况(这可能会在其他用例中引发问题,当用户希望看到页面处于他们离开的状态时)。

所以我想我在这里遗漏了一些东西。 如何强制后退按钮在浏览器加载最后一页的状态下加载缓存代码,而不是在它离开的状态下?

标签: javascripthtmlsafariback

解决方案


实际上,我缺少的是所谓的“后退/前进缓存”或bfcache。作为性能优化,bfcache存储页面的完整快照,包括我的小 JavaScript 在 Safari 中所做的更改,而不是在 Chrome 中。

事实证明,我们可以轻松地对bfcache事件做出反应:

<script type="text/javascript">
    function loading(){  // replace content by Loading ...
        document.getElementById("loading").style.display = 'block';
        document.getElementById("content").style.display = 'none';
    }
    function makeContentVisisble() {  // replace Loading ... by content
        document.getElementById('loading').style.display = 'none';
        document.getElementById('content').style.display = 'block';
    }
</script>

<body onpageshow="makeContentVisisble()"> <!-- called on browser back -->
    <div id="loading" class="invisible">
        Loading ...
    </div>
    <div id="content">
        <a href="/time/consuming/service/call" onclick="loading();">Work miracles.</a>

这样,浏览器返回在 Chrome 和 Safari 中都能顺利运行(而且速度很快,无需从后端重新加载页面)。

在 2020 年的这个失败的当前博客中找到有关bfcache的更多详细信息: https ://web.dev/bfcache/


推荐阅读