如何使用 jQuery 为所有浏览器绑定到 localStorage 更改事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4671852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 17:41:35  来源:igfitidea点击:

How to bind to localStorage change event using jQuery for all browsers?

jqueryhtmlgoogle-chrome

提问by David Glenn

How do I bind a function to the HTML5 localStorage change event using jQuery?

如何使用 jQuery 将函数绑定到 HTML5 localStorage 更改事件?

$(function () {

  $(window).bind('storage', function (e) {
    alert('storage changed');
  });

  localStorage.setItem('a', 'test');

});

I've tried the above but the alert is not showing.

我已经尝试了上述方法,但没有显示警报。

Update: It works in Firefox 3.6 but it doesn't work in Chrome 8 or IE 8 so the question should be more 'How to bind to localStorage change event using jQuery for all browsers?'

更新:它在 Firefox 3.6 中有效,但在 Chrome 8 或 IE 8 中无效,所以问题应该更多是“如何使用 jQuery 为所有浏览器绑定到 localStorage 更改事件?”

回答by David Glenn

It turns out that this is actually working correctly and I have misinterpreted the specification

事实证明,这实际上工作正常,我误解了规范

When the setItem(), removeItem(), and clear() methods are called on a Storage object x that is associated with a local storage area, if the methods did something, then in every Document object whose Window object's localStorage attribute's Storage object is associated with the same storage area, other than x, a storage event must be fired

当 setItem()、removeItem() 和 clear() 方法在与本地存储区域关联的 Storage 对象 x 上被调用时,如果这些方法做了某事,那么在每个 Document 对象中,其 Window 对象的 localStorage 属性的 Storage 对象是与相同的存储区域相关联,除了 x,必须触发存储事件

In other words, a storage event is fired on every window/tab exceptfor the one that updated the localStorageobject and caused the event.

换句话说,除了更新localStorage对象并引发事件的窗口/选项卡之外,每个窗口/选项卡都会触发存储事件。

So the event was not fired because I only had one window/tab open. If I place the above code in a page and open the page in two tabs I would see the event fired in the second tab.

所以事件没有被触发,因为我只打开了一个窗口/选项卡。如果我将上面的代码放在一个页面中并在两个选项卡中打开页面,我会看到在第二个选项卡中触发的事件。

This answer on the problem contains more details.

这个问题的答案包含更多细节。

回答by Flimm

Here's how to do it in JQuery:

下面是如何在 JQuery 中做到这一点:

 $(window).bind('storage', function (e) {
     console.log(e.originalEvent.key, e.originalEvent.newValue);
 });

Accessing e.keydirectly does not work. You need to use e.originalEvent.key.

e.key直接访问不起作用。您需要使用e.originalEvent.key.

Some browsers will only send storage notifications to other tabs, and some won't. (Firefox will send storage events to its own tab, but with keyset to null, it seems like).

有些浏览器只会将存储通知发送到其他选项卡,有些则不会。(Firefox 会将存储事件发送到它自己的选项卡,但key似乎设置为 null)。

回答by kmoney12

One thing to mention is that the event handler is only called on .setItemif the item actuallychanges. I was ripping my hair out trying to get this to work until I realized you can't keep running setItem with the same value.

需要提及的一件事是事件处理程序仅.setItem在项目实际更改时才被调用。我一直在努力让它工作,直到我意识到你不能继续使用相同的值运行 setItem 。

I am on Chrome Version 54.0.2840.71 m

我在 Chrome 版本 54.0.2840.71 m

Here is a test (open this in two browser tabs).

这是一个测试(在两个浏览器选项卡中打开它)。

if (window.addEventListener)
            addEventListener('storage', storage_event, false);
        else if (window.attachEvent)
            attachEvent('onstorage', storage_event, false);
        function storage_event(e) {
            console.log("Time is now "+ e.newValue);
        }

        setInterval(function () {
            var time=new Date().getTime();
            localStorage.setItem("time", time);
            console.log("Setting time to "+time);
        }, 1000)

回答by Mac

You could always use a utility like localDataStorageto fire the events for you, in the same window/tab, whenever a key value changes, such as those made by the set or remove methods. You can also use it to transparently set/get any of the following "types": Array, Boolean, Date, Float, Integer, Null, Object or String.

您始终可以使用像localDataStorage这样的实用程序在同一窗口/选项卡中为您触发事件,只要键值发生更改,例如由 set 或 remove 方法生成的那些。您还可以使用它来透明地设置/获取以下任何“类型”:数组、布尔值、日期、浮点数、整数、空值、对象或字符串。

[DISCLAIMER] I am the author of the utility [/DISCLAIMER]

[免责声明] 我是该实用程序的作者 [/免责声明]

Once you instantiate the utility, the following snippet will allow you to monitor the events (in vanilla JS, since jQuery examples have already been given):

实例化该实用程序后,以下代码段将允许您监视事件(在 vanilla JS 中,因为已经给出了 jQuery 示例):

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
);