14

From many sources, I have found that the local storage events only fire in windows/tabs that did not originate the change.

My question is, is there any way I could detect change from the same window? Or perhaps override the functionality to force the event to fire within the same window/tab?

It just seems impractical to not include the option, but I cannot find a way to do it.

Thanks

Troy Cosentino
  • 4,658
  • 9
  • 37
  • 59
  • [Some already did](http://stackoverflow.com/a/4689033). For the others, `$(window).trigger("storage")` (or the native equivalent) should do it. – Bergi Aug 06 '13 at 21:33
  • hmm I thought I tried that first and it didn't work. I will give it a try again shorty, thank you – Troy Cosentino Aug 06 '13 at 22:05
  • @Bergi that works nicely, thank you. How would I include the correctly formatted event object? – Troy Cosentino Aug 06 '13 at 22:22
  • I tried: `$(window).trigger('storage', {}, {originalEvent: {key: 'selectedAdmins'}});` – Troy Cosentino Aug 06 '13 at 22:23
  • @Bergi can you provide a working example, please? I just tried invoking $(window).trigger("storage") after I added something in the local storage but an event wasn't fired in the same window. – user3281466 Aug 28 '14 at 15:07
  • Do you use jQuery? How did you set up your listeners? – Bergi Aug 28 '14 at 15:11
  • @user3281466 I uploaded the code I am using that works. Hopefully that helps! – Troy Cosentino Aug 28 '14 at 21:41
  • @Bergi pastebin.com/7EthAJ0f – user3281466 Aug 29 '14 at 09:20
  • `trigger` does only trigger jQuery-attached event handlers unfortunately: http://jsfiddle.net/1gw7h8bm/ - just bind via `$(window).on` instead of `addEventListener`. That's why I said "*or the [native equivalent](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events)*" if you don't want to use jQuery. – Bergi Aug 29 '14 at 11:06
  • @Bergi thanks this triggers the event but the key and value are null when I tried picking them up: http://jsfiddle.net/78e7puhn/ Why is that? hope I'm not getting too annoying with the questions. – user3281466 Aug 29 '14 at 13:20
  • 2
    You have yourself put them as the `.originalEvent` :-) See http://jsfiddle.net/78e7puhn/2/ – Bergi Aug 29 '14 at 13:47
  • @Bergi thanks I understand now. This was actually the OP's code which I didn't quite understand. I think you should post this as an answer. – user3281466 Aug 29 '14 at 14:04
  • IE does it . And i am removing it from IE and you are asking to add this event. Actually when you change data you can invoke any event after setdata in same tab. – alternatefaraz Apr 15 '15 at 18:58

5 Answers5

3

FYI, here is what I ended up with.

localStorage.setItem('selectedOrgs', JSON.stringify(this.selectedOrgs));

// trigger the event manually so that it triggers in the same window
// first create the event
var e = $.Event("storage");

// simulate it being an actual storage event
e.originalEvent = {
    key: 'selectedOrgs',
    oldValue: prev,
    newValue: JSON.stringify(this.selectedOrgs)
};

// Now actually trigger it
$(window).trigger(e);

Note: I only use oldValue and newValue.. if you use other attributes make sure and set them appropriately.

You could also overwrite localStorage.setItem so that it fires in the current window in a similar way.

Troy Cosentino
  • 4,658
  • 9
  • 37
  • 59
  • Hey, thanks a lot for posting your code. But I don't understand why my event is still not firing. does $(window).trigger(e); only trigger it in other windows? Basically, I'm just trying to trigger the storage change event in the same window that made the change. Here is what I wrote based on your code: pastebin.com/7EthAJ0f – user3281466 Aug 29 '14 at 09:20
  • That jsfiddle is not the same thing at all. Its creating a custom event that just happens to be called `storage` and then triggers it. If you were to change the key in the event object you would see that it doesn't get saved to localStorage and the key '1' would get set but not fired. – Eddie Monge Jr Jan 14 '15 at 20:01
  • While this might not _technically_ answer the question, I gave it a plus one because it's a great way to simulate the storage event during an integration test. Thanks! – Scott Norvell Feb 17 '16 at 15:27
  • Thanks! it worked. For anyone confused, he's using jquery, if you're using react, `npm install jquery` and the use it like `import $ from 'jquery'` and then use it as mentioned in the answer i.e. `$(window).trigger('storage');`. Here is the doc for jquery .trigger() https://api.jquery.com/trigger/ – Taimoor Abdullah Khan Nov 29 '21 at 15:42
2

Patch the localStorage.setItem function to manually generate a "storage" event within the same window:

const origSetItem = window.localStorage.setItem;

window.localStorage.setItem = function setItem(key, value) {
  // Retrieve old value before we store the new one
  let oldValue = window.localStorage.getItem(key);

  // Store in LocalStorage
  const result = origSetItem.apply(this, arguments);

  // Manually fire a "storage" event so this window is alerted. On its own, 
  // localStorage.setItem() only fires a "storage" event for other tabs.
  const e = new StorageEvent('storage', {
    storageArea: window.localStorage,
    key,
    oldValue,
    newValue: value,
    url: window.location.href,
  });
  window.dispatchEvent(e);

  return result;
}

Now anytime localStorage.setItem() is called, the window's "storage" event will fire.

JWess
  • 602
  • 7
  • 17
1

Whenever you want to trigger it on the same tab, add this line

window.dispatchEvent(new Event("storage"));

Add an event listener for the page

window.addEventListener('storage', storageEventHandler, false);

function storageEventHandler(e) {
    console.log("Hello!")
}

That's all

Ahmet Firat Keler
  • 2,603
  • 2
  • 11
  • 22
0

Yes, you can generate unique id for each tab and compare them, look how this guy did here Another solution I found based on the same idea, generate and compare unique ids.. here

Community
  • 1
  • 1
Denis
  • 2,429
  • 5
  • 33
  • 61
0

This is easily handled with localDataStorage, where you can transparently set/get any of the following "types": Array, Boolean, Date, Float, Integer, Null, Object or String. Of course, it also fires events in the same window/tab for key value changes, such as those made by the set or remove methods.

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

Once you instantiate the utility, the following snippet will allow you to monitor the events:

function nowICanSeeLocalStorageChangeEvents( e ) {
    console.log(
        "subscriber: "    + e.currentTarget.nodeName + "\n" +
        "timestamp: "     + e.detail.timestamp + " (" + new Date( e.detail.timestamp ) + ")" + "\n" +
        "prefix: "        + e.detail.prefix  + "\n" +
        "message: "       + e.detail.message + "\n" +
        "method: "        + e.detail.method  + "\n" +
        "key: "           + e.detail.key     + "\n" +
        "old value: "     + e.detail.oldval  + "\n" +
        "new value: "     + e.detail.newval  + "\n" +
        "old data type: " + e.detail.oldtype + "\n" +
        "new data type: " + e.detail.newtype
    );
};
document.addEventListener(
    "localDataStorage"
    , nowICanSeeLocalStorageChangeEvents
    , false
);
Mac
  • 1,432
  • 21
  • 27