如何将事件绑定到 sessionStorage?

Posted

技术标签:

【中文标题】如何将事件绑定到 sessionStorage?【英文标题】:How do I bind event to sessionStorage? 【发布时间】:2012-05-02 20:35:59 【问题描述】:

我可以成功地将事件绑定到 localStorage(使用 jquery):

$(window).bind('storage', function(e)

    alert('change');
);

localStorage.setItem('someItem', 'someValue');

如果我使用 sessionStorage,该事件将不会触发:

 $(window).bind('storage', function(e)

    alert('change');
);

sessionStorage.setItem('someItem', 'someValue');

这是为什么?

【问题讨论】:

我正在 Chrome 中测试这个。它必须在 Chrome、FF 和 IE9+ 中运行。我还应该提到,我需要在另一个选项卡/窗口(同一浏览器)中触发该事件。 我没有看到这个事件在 Chrome 中被触发,使用 localStorage 【参考方案1】:

sessionStorage 对于每个选项卡都是隔离的,因此它们无法通信。 sessionStorage 的事件仅在同一选项卡上的帧之间触发。

编辑:

我做了以下例子:

http://codepen.io/surdu/pen/QGZGLO?editors=1010

示例页面有两个按钮可以触发本地和会话存储更改。

它还将 iframe 嵌入到另一个监听存储事件更改的 codepen:

http://codepen.io/surdu/pen/GNYNrW?editors=1010 (你应该在另一个标签页中打开它。)

您会注意到,当您按下“写入本地”按钮时,在 iframe 和打开的选项卡中都会捕获事件,但是当您按下“会话写入”时,只有嵌入的 iframe 会捕获事件。

【讨论】:

我同意@NicolaeSurdu。我需要通过跨多个选项卡的 StorageEvent 跟踪属性更新,而 sessionStorage 不起作用。当我切换到使用 localStorage 实例时,StorageEvent 按预期触发。通过 localStorage 存储的属性是持久的,因此您需要在使用完毕后手动将它们从存储中删除。【参考方案2】:

这就是我认为的方式。来自spec(强调添加):

setItem()removeItem()clear() 方法在 Storage 与会话存储区域关联的对象 x,如果 这些方法做了一些事情,然后在每个 Document 对象的 Window 对象的 sessionStorage 属性的 Storage 对象与 相同的存储区域,除了 x,必须触发存储事件

认为这意味着该事件将在共享会话存储对象的任何其他文档中触发,但不会在导致事件触发的文档中触发。

更新

这是另一个very similar question,似乎与我上面提到的一致(答案引用了规范中的同一段)。

【讨论】:

我希望事件在另一个选项卡/窗口(“x 以外”)中触发。 sessionStorage 是否只适用于当前窗口/标签页? 不,它适用于会话。该事件应该在其他选项卡/窗口中触发,但它应该在同一个文档中触发。 是否可以强制事件在同一个窗口中触发?【参考方案3】:

这个问题似乎获得了相当多的意见,所以我将把它作为额外信息发布。

如果你想专门响应 sessionStorage 对象的更新,你可以忽略 localStorage 引起的事件:

$(window).on('storage',function(e)
   if(e.originalEvent.storageArea===sessionStorage)
     alert('change');
    
   // else, event is caused by an update to localStorage, ignore it
);

我讨厌 jQuery,所以也会发布原生版本:

window.addEventListener('storage',function(e)
   if(e.storageArea===sessionStorage)
     alert('change');
    
   // else, event is caused by an update to localStorage, ignore it
);

【讨论】:

以防万一有人想知道为什么这不起作用。它的设计目的是仅当用户打开多个相同域的标签时才起作用,而不是您可能认为它在当前标签上触发的位置。 它不适用于仅 1 个标签?这对逻辑来说是一场灾难

以上是关于如何将事件绑定到 sessionStorage?的主要内容,如果未能解决你的问题,请参考以下文章

将事件和本地 vue 变量传递给绑定函数的惯用方式

2.javascript之缓存 localStorage 和sessionStorage之间的区别

如何将模糊事件绑定到实时点击事件?

如何将事件处理程序绑定到 jQuery 中的实例?

如何将 TAO 事件通道绑定到特定的命名服务

如何将点击事件绑定到 Tkinter 中的画布? [关闭]