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

时间:2023-01-02 23:58:44

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更改事件?'

4 个解决方案

#1


75  

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

当在与本地存储区域相关联的存储对象x上​​调用setItem(),removeItem()和clear()方法时,如果方法执行了某些操作,则在Window对象的localStorage属性的Storage对象的每个Document对象中都是与x相同的存储区域相关联,必须触发存储事件

In other words, a storage event is fired on every window/tab except for the one that updated the localStorage object 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.

关于该问题的答案包含更多细节。

#2


10  

Here's how to do it in JQuery:

以下是如何在JQuery中执行此操作:

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

Accessing e.key directly does not work, you need to use e.originalEvent.key.

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

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

有些浏览器只向其他标签发送存储通知,有些则不会。 (Firefox会将存储事件发送到自己的选项卡,但是如果将键设置为null,则看起来像)。

#3


4  

One thing to mention is that the event handler is only called on .setItem if the item actually changes. 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)

#4


2  

You could always use a utility like localDataStorage to 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方法所做的更改。您还可以使用它透明地设置/获取以下任何“类型”:Array,Boolean,Date,Float,Integer,Null,Object或String。

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

[免责声明]我是该实用程序的作者[/ 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
);

#1


75  

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

当在与本地存储区域相关联的存储对象x上​​调用setItem(),removeItem()和clear()方法时,如果方法执行了某些操作,则在Window对象的localStorage属性的Storage对象的每个Document对象中都是与x相同的存储区域相关联,必须触发存储事件

In other words, a storage event is fired on every window/tab except for the one that updated the localStorage object 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.

关于该问题的答案包含更多细节。

#2


10  

Here's how to do it in JQuery:

以下是如何在JQuery中执行此操作:

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

Accessing e.key directly does not work, you need to use e.originalEvent.key.

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

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

有些浏览器只向其他标签发送存储通知,有些则不会。 (Firefox会将存储事件发送到自己的选项卡,但是如果将键设置为null,则看起来像)。

#3


4  

One thing to mention is that the event handler is only called on .setItem if the item actually changes. 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)

#4


2  

You could always use a utility like localDataStorage to 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方法所做的更改。您还可以使用它透明地设置/获取以下任何“类型”:Array,Boolean,Date,Float,Integer,Null,Object或String。

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

[免责声明]我是该实用程序的作者[/ 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
);