在问了这个问题六年后,我发现仍然没有足够的答案。它应该实现以下所有目的:
- 关闭浏览器(或域的所有选项卡)后,清除“本地存储”
- 如果至少有一个标签处于活动状态,则跨标签保留本地存储
- 重新加载单个标签时保留本地存储
在每个页面加载开始时执行此javascript,以实现上述目的:
((nm,tm) => {
const
l = localStorage,
s = sessionStorage,
tabid = s.getItem(tm) || (newid => s.setItem(tm, newid) || newid)((Math.random() * 1e8).toFixed()),
update = set => {
let cur = JSON.parse(l.getItem(nm) || '{}');
if (set && typeof cur[tabid] == 'undefined' && !Object.values(cur).reduce((a, b) => a + b, 0)) {
l.clear();
cur = {};
}
cur[tabid] = set;
l.setItem(nm, JSON.stringify(cur));
};
update(1);
window.onbeforeunload = () => update(0);
})('tabs','tabid');
编辑:这里的基本思路如下:
- 从头开始时,会在名为的密钥中为会话存储分配一个随机ID
tabid
- 然后使用称为键的密钥设置本地存储,该键
tabs
包含一个对象,这些键tabid
设置为1。
- 卸载选项卡后,本地存储的
tabs
更新为包含tabid
设置为0 的对象。
- 如果重新加载了选项卡,则首先将其卸载,然后恢复。由于
tabid
存在会话存储的密钥,因此不会清除tabs
带有本地存储的子密钥tabid
的本地存储密钥。
- 卸载浏览器后,所有会话存储将被清除。恢复会话时,存储
tabid
将不再存在,并且tabid
将生成一个新的会话存储。由于本地存储没有为此的子项tabid
,也没有任何其他项tabid
(所有会话已关闭),因此将其清除。
- 创建新标签后,
tabid
会话存储中会生成一个新标签,但是由于至少有一个tabs
[ tabid
],因此不会清除本地存储