javascript 存储事件未激发

nr7wwzry  于 2022-12-25  发布在  Java
关注(0)|答案(8)|浏览(179)

附加事件:

$(window).on("storage", function (e) {
   //callback not getting hit
});

正在尝试激发事件:

localStorage.setItem("test", "123");

我打开了两个选项卡,都在监听存储事件。我可以看到两个选项卡上的localStorage都得到了正确的更新。但是,当我在一个选项卡上更改localStorage时,另一个选项卡从未触发事件。有什么想法吗?
已在Chrome/Firefox上试用。域名格式为https://www.xxx.yyy.zzz

yebdmbv4

yebdmbv41#

StorageEvent在具有相同域的不同页中激发。
来自MDN
只要对Storage对象进行更改,就会激发StorageEvent。
这在进行更改的同一个页面上不起作用--这实际上是域中其他页面使用存储来同步所做更改的一种方式。

3duebb1j

3duebb1j2#

正如回答中的其他人所指出的,只有在(同一应用程序的)另一个浏览器的选项卡/窗口中更改了 localStorage,而在当前选项卡的上下文中没有时,才会(由侦听器)拾取storage事件。

检测 * 当前选项卡 * 中的存储更改:

window.addEventListener('storage', console.log)

window.localStorage.setItem('test', '123')
window.dispatchEvent( new Event('storage') ) // <-----

调度手动storage事件。
这将有效地触发storage事件监听器 * 两次 * 在其他标签/窗口(同一应用程序),但在某些情况下,这应该不是一个问题。

eqzww0vc

eqzww0vc3#

如果甚至在不同的标签页/页面之间测试,仍然看不到事件...我发现,只有当键已经存在时,事件才会触发。
看起来更像是一个onchange事件。
如果undefined为偶数,则将localStorage键设置为默认值,然后进行测试。
我会称之为Chrome bug,因为Firefox和Safari都是正确的,但它就是这样。

moiiocjp

moiiocjp4#

vsync's answer above的另一点是,您可以触发StorageEvent而不是Event,并传入一个对象,以便触发的事件与浏览器默认值匹配。

const oldValue = window.localStorage.getItem('test');
window.localStorage.setItem('test', newValue);
const event = new StorageEvent('storage', {
  key: 'test',
  oldValue,
  newValue,
  ...
});

window.dispatchEvent(event);
vaj7vani

vaj7vani5#

问题是由代码中的document.domain重写引起的。在我删除document.domain设置器后,事件正常工作。
似乎这是由Chrome中的一个错误引起的。
https://bugs.chromium.org/p/chromium/issues/detail?id=136356&q=label%3AOWP-Standards-Compatibility&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Cr%20Status%20Owner%20Summary%20OS%20Modified

kpbpu008

kpbpu0086#

window.addEventListener('storage', function (e) {
      console.log("storage event occured here");
},false);

存储列表器在其他选项卡中调用,而不是源选项卡。只需将调试器添加到其他选项卡。

wlwcrazw

wlwcrazw7#

你可以使用localDataStorage这样的工具,在同一个窗口/标签页中,每当键值发生变化时,比如set或remove方法所做的变化,你也可以使用它来透明地设置/获取以下任何"类型":数组、布尔值、日期、浮点数、整数、Null、对象或字符串。
[免责声明]我是该实用程序的作者[/免责声明]
示例化实用程序后,以下代码段将允许您监视事件:

function localStorageChangeEvents( e ) {
    console.log(
        "timestamp: "     + e.detail.timestamp + " (" + new Date( e.detail.timestamp ) + ")" + "\n" +
        "key: "           + e.detail.key     + "\n" +
        "old value: "     + e.detail.oldval  + "\n" +
        "new value: "     + e.detail.newval  + "\n"
    );
};
document.addEventListener(
    "localDataStorage"
    , localStorageChangeEvents
    , false
);
sd2nnvve

sd2nnvve8#

如果从一个标签页注销,我试图从其他标签页注销。我面临的问题是一遍又一遍地设置相同的值。
这就是为什么存储事件不会在其他标签中触发的原因。一个简单的黑客是每次添加一个盐/随机的东西来发射事件。

window.localStorage.setItem('logout-event',Math.random().toString())

然后事件在其他标签页中可用!处理来自其他标签页的事件的更好方法是使用BroadcastChannel

相关问题