javascript - 浏览器后退按钮在 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 中,浏览器后退按钮适用于这种情况(这可能会在其他用例中引发问题,当用户希望看到页面处于他们离开的状态时)。
所以我想我在这里遗漏了一些东西。 如何强制后退按钮在浏览器加载最后一页的状态下加载缓存代码,而不是在它离开的状态下?
解决方案
实际上,我缺少的是所谓的“后退/前进缓存”或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/
推荐阅读
- javascript - How to add @angular/material to an old angular project?
- python - 使用 numpy 以矢量化形式转换 for 循环函数
- vb.net - 调用程序集的入口点而不显示任何窗口 - VB.Net
- amazon-web-services - 获取不存在“Access-Control-Allow-Origin”标头 AWS api 网关
- git - VSCode Git 退出并保存提交编辑器?
- c++ - C++ 中的井字游戏极小极大算法
- django - 克隆一个 Django 模型实例对象并将其保存到另一个具有相同字段的模型中
- html - HTML 自动播放歌曲和 StartAt
- mysql - 如何为我的数据库建模一对多关系
- javascript - 如何循环 setTimeout 幻灯片 javascript