2 回答
TA贡献1796条经验 获得超7个赞
我会建议你使用localStorage
这个具有相当好的存储容量。
您仅限于其中的字符串,因此您需要将所有内容与 JSON 相互转换以获得最佳结果。
你存储什么取决于你。我将创建一个具有各种属性的对象,例如当前滚动高度、上次请求的索引和一个数组,其中包含您到目前为止从 AJAX 中提取的所有内容(以及您在页面加载时创建的所有内容)。如果您要在多个页面上使用此逻辑,或者只是更改每页的键,您可能还想存储它所在的页面。但是,如果您共享一个密钥,您也可以完全跳过对您已经拥有的数据的 AJAX 调用,并且您认为自己的业务逻辑是“新鲜的”。
下面是一些示例代码。如果您按下开始按钮并让它运行几秒钟,您将看到列表随着时间戳而增长。如果您随后刷新页面,所有内容仍将存在。
首先,一些 HTML 让我们工作,一个开始和停止的按钮以及我们将写入的列表。
<button id="start">Start</button>
<button id="stop">Stop</button>
<ul id="list">
</ul>
然后是 JS,内联注释应该可以解释一切:
// This is the interval key, used when stopping the interval code
let iv;
const cache_key = 'my-cache-key';
function stop() {
window.clearInterval( iv );
}
function start() {
iv = window.setInterval( tick, 1000 );
}
function makeLi( text ) {
const li = document.createElement( 'li' );
li.appendChild( document.createTextNode( text ) );
return li;
}
// Run once a second
function tick() {
// Create a timestamp
const ts = new Date().getTime();
// Store it to local session
store( ts );
// Append to our list
const ul = document.getElementById( 'list' );
ul.appendChild( makeLi( ts ) );
}
function store( text ) {
// See if we have our key
let items = window.localStorage.getItem( cache_key );
// Parse it as JSON or set it to an empty array to start
if ( items ) {
items = JSON.parse( items );
} else {
items = [];
}
// Append our current key
items.push( text );
// Push it back
window.localStorage.setItem( cache_key, JSON.stringify( items ) );
}
// One page load, recreate all items
function load() {
const ul = document.getElementById( 'list' );
let items = window.localStorage.getItem( cache_key );
if ( !items ) {
return;
}
items = JSON.parse( items );
items
.forEach(
( item ) => {
ul.appendChild( makeLi( item ) )
}
);
}
// Click handlers for the button
document.getElementById( 'start' ).addEventListener( 'click', start );
document.getElementById( 'stop' ).addEventListener( 'click', stop );
// Reload anything previously stored on page refresh
window.addEventListener( 'load', load );
至于你在本地存储中存储什么,这取决于。如果您的 DOM 很复杂但很短,您可以存储它outerHTML的,但这有点难看。相反,我会存储您从 AJAX 收到的用于创建对象的最少字段数。
此外,无论您存储什么,我都建议在您的对象上有一个名为“版本”之类的属性,并且每当您向 AJAX 逻辑引入新功能时手动增加它。这样,如果有人带着不再有意义的数据返回您的页面,您的应用程序可以检测到它并将其丢弃。
这个示例应用程序存储一个非常简单的数组,但就像我说的,您可能想要存储一个对象并且您还想要执行验证和清理,就像您在 AJAX 中所做的那样。
编辑
我还应该补充一点,您需要确保您的图像等资源在未来缓存过期,以便从本地缓存中获得额外的站点速度。
根据我的评论,这个网站(已有 4 年历史)表示 97.6% 的人启用了本地存储,所以我绝对会使用它,因为降级只是“最新的”,这仍然是一个不错的体验。
如果您在参考站点上打开您的开发人员工具,您可以检查本地存储的应用程序部分,您会在那里找到我正在谈论的版本。
TA贡献1890条经验 获得超9个赞
这个问题太宽泛了,但由于它不能在有赏金的情况下关闭,所以我不妨用同样宽泛的答案来回答。
你真的需要这个吗?为什么不在新标签页中打开全尺寸图片?或者为什么不离开页面就打开它们?如果您想要后退/前进功能,您可以使用History API 。您将尽可能节省所有流量。此外,在显示全尺寸图像时,您可以允许用户使用箭头键和其他一些很酷的员工在全尺寸图像之间移动。
关于
但我认为这不是一个好主意,因为加载大量这样的内容会影响性能
正确的缓存 - 不是真的。图像不会被重新加载...当然,如果您通过 url 加载它们而不是以其他一些奇怪的方式加载它们。
关于问题的标题:我们真的应该谈论重建状态而不是恢复状态。因为对于这个:
您能否保留使用 ajax 的页面的动态内容,以便在用户返回时恢复?
答案是:“不,你不能”。不是因为它完全不可能,而是因为你肯定会失败。要存档此目标,您需要
在每次更改时将应用程序的每个变量序列化。包括有关 DOM 动态更改的信息。
并非所有东西都易于序列化:
Promise
s、WeakMap
s、Symbol
s、具有循环引用的数据等。接下来,您需要将它们反序列化回来。这也可能是一个挑战。特别是,如果在序列化和反序列化之间服务器端发生了一些变化。(可能扔掉所有东西重新开始更容易)
此外,您还需要决定是否应该这样做。例如,如果用户在一个月后访问您的页面——您真的要显示一个月前的状态吗?
但如果我们谈论存储一些重要变量并从中重新创建状态,那么答案是:“是的,它一直在发生”。
在客户端存储数据有不同的方法(甚至是数据库!),在服务器端存储数据更是如此。
他们都适合自己的场景。在不知道这些情况的情况下很难说什么是最好的方法。
但在这种特殊情况下,您只需要存储 1 或 2 个变量。而使用 cookie 可能是最好的选择。虽然现在如果您使用 cookie,您需要显示一些烦人的消息。由于欧盟 cookie 指令。但它们易于使用,例如,如果您决定在一个月后向用户呈现一个全新的状态,您只需要为 cookie 设置到期日期,而如果您使用
localStorage
.在这个显然不是商业站点的地方,可能不需要服务器端存储。
- 2 回答
- 0 关注
- 93 浏览
添加回答
举报