Skip to content

Instantly share code, notes, and snippets.

@johan
Last active September 26, 2019 14:19

Revisions

  1. johan revised this gist Dec 28, 2015. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions notifications.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    var header = document.getElementById('title');
    var count = getCount();
    var title = document.title;
    var title = document.title.replace(/s$/, '');

    updateCount(count);
    try {
    @@ -10,7 +10,8 @@ try {
    }

    function updateCount(n) {
    var t = header.innerHTML = document.title = title + ': ' + n;
    var s = n === 1 ? '' : 's';
    var t = header.innerHTML = document.title = n + ' ' + title + s;
    if (frameElement) { // for bl.ocks.org's parent frame
    parent.document.title = t;
    frameElement.style.height = '125px';
  2. johan revised this gist Sep 24, 2015. 1 changed file with 8 additions and 9 deletions.
    17 changes: 8 additions & 9 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,33 +1,32 @@
    Your website has some kind of notifications system showing the user a count
    Take a website with some kind of notifications system showing the user a count
    of their unread notifications or similar. ([Facebook](https://facebook.com/),
    [Google+](https://plus.google.com/), [GMail](https://mail.google.com/) et c.)

    Now perform an action in one browser tab, that changes or clears the count.
    Does the change immediately propagate to all other tabs that browser has open?
    Does this immediately propagate to all other tabs you have open on the site?

    If not – this example is for you!

    As it happens, this is really easy to do in
    [browsers supporting `localStorage`](http://caniuse.com/#search=localStorage)
    (which is _all_ of them released since 2009 – including IE8!),
    (which is _all_ of them, back to 2009; even IE8),
    by subscribing to the [`storage` event](https://developer.mozilla.org/en-US/docs/Web/Events/storage),
    as demonstrated in this example.

    Try opening this page in two browser tabs or windows and click the buttons.
    Open this page in two browser tabs or windows, and click the buttons.
    The event fires on all _other_ windows accessing the same `localStorage`,
    so the update will propagate over your whole site by default, as you want.

    Your most recently hired front-end developer can pull this off single-handedly.
    At the time of posting this (September 23, 2015),
    none of the social services linked are this kind to their users.

    If your site is using `alert()` or similar (and I _may_ be looking at you now,
    [Google Calendar](https://calendar.google.com/)!)
    If your site is using `alert()` or similar
    ([Google Calendar](https://calendar.google.com/) comes to mind)
    to alert the user of some kind of alarm or scheduled event you have set,
    similarly: please only fire off that alert in _one_ of those open windows.
    similarly: please only fire off that alert in _one_ of all open windows.

    You can apply this basic technique for cross-tab synchronization
    to make sure you don't send off a dozen tabs or more
    grabbing user focus in a wild dance of confusion, frustration and aggravation.

    Thank you, and happy hacking!
    Thanks for reading, and happy hacking!
  3. johan revised this gist Sep 24, 2015. 1 changed file with 0 additions and 0 deletions.
    Binary file added thumbnail.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  4. johan revised this gist Sep 24, 2015. 2 changed files with 12 additions and 6 deletions.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,7 @@
    </head>
    <body>

    <h1>Unseen Notifications</h1>
    <h1 id="title">Unseen Notifications</h1>

    <button id="add">Add to unseen</button>
    <button id="clr">Clear unseen</button>
    16 changes: 11 additions & 5 deletions notifications.js
    Original file line number Diff line number Diff line change
    @@ -1,12 +1,16 @@
    var header = document.querySelector('h1');
    var header = document.getElementById('title');
    var count = getCount();
    var title = document.title;

    updateCount(count);
    window.addEventListener('storage', onStorageChange);
    try {
    window.addEventListener('storage', onStorageChange);
    } catch(e) {
    window.attachEvent('onstorage', onStorageChange);
    }

    function updateCount(n) {
    var t = header.textContent = document.title = title + ': ' + n;
    var t = header.innerHTML = document.title = title + ': ' + n;
    if (frameElement) { // for bl.ocks.org's parent frame
    parent.document.title = t;
    frameElement.style.height = '125px';
    @@ -24,10 +28,12 @@ function setCount(n) {

    function onStorageChange(e) {
    if (e.key !== 'unseenNotificationCount') return;
    var t = (new Date(e.timeStamp)).toISOString();
    var v = e.newValue;
    console.log('%s: %s = %s', t, e.key, v);
    updateCount(v);
    try {
    var t = (new Date(e.timeStamp)).toISOString();
    console.log('%s: %s = %s', t, e.key, v);
    } catch(e) {}
    }

    document.body.addEventListener('click', function(e) {
  5. johan revised this gist Sep 24, 2015. 3 changed files with 28 additions and 11 deletions.
    31 changes: 22 additions & 9 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,15 @@
    If your website has some kind of notifications system showing the user a count
    of their unread notifications or similar ([Facebook](https://facebook.com/),
    [Google+](https://plus.google.com/), [GMail](https://mail.google.com/) or so),
    as soon as your user performs an action in one window that changes the count,
    please make the change immediately propagate to all open tabs in that browser,
    without the user having to revisit / reload / click "notifications", or similar.

    This is easy to do in
    Your website has some kind of notifications system showing the user a count
    of their unread notifications or similar. ([Facebook](https://facebook.com/),
    [Google+](https://plus.google.com/), [GMail](https://mail.google.com/) et c.)

    Now perform an action in one browser tab, that changes or clears the count.
    Does the change immediately propagate to all other tabs that browser has open?

    If not – this example is for you!

    As it happens, this is really easy to do in
    [browsers supporting `localStorage`](http://caniuse.com/#search=localStorage)
    (which is all of them released since 2009, i e IE8+),
    (which is _all_ of them released since 2009 – including IE8!),
    by subscribing to the [`storage` event](https://developer.mozilla.org/en-US/docs/Web/Events/storage),
    as demonstrated in this example.

    @@ -18,3 +20,14 @@ so the update will propagate over your whole site by default, as you want.
    Your most recently hired front-end developer can pull this off single-handedly.
    At the time of posting this (September 23, 2015),
    none of the social services linked are this kind to their users.

    If your site is using `alert()` or similar (and I _may_ be looking at you now,
    [Google Calendar](https://calendar.google.com/)!)
    to alert the user of some kind of alarm or scheduled event you have set,
    similarly: please only fire off that alert in _one_ of those open windows.

    You can apply this basic technique for cross-tab synchronization
    to make sure you don't send off a dozen tabs or more
    grabbing user focus in a wild dance of confusion, frustration and aggravation.

    Thank you, and happy hacking!
    3 changes: 2 additions & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,7 @@
    <html>
    <head>
    <title>Unseen Notifications</title>
    <style>body { margin: 20px; }</style>
    </head>
    <body>

    @@ -12,4 +13,4 @@ <h1>Unseen Notifications</h1>

    <script src="notifications.js"></script>
    </body>
    </html>
    </html>
    5 changes: 4 additions & 1 deletion notifications.js
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,10 @@ window.addEventListener('storage', onStorageChange);

    function updateCount(n) {
    var t = header.textContent = document.title = title + ': ' + n;
    if (frameElement) parent.document.title = t; // for bl.ocks.org's parent frame
    if (frameElement) { // for bl.ocks.org's parent frame
    parent.document.title = t;
    frameElement.style.height = '125px';
    }
    }

    function getCount() {
  6. johan revised this gist Sep 24, 2015. 2 changed files with 22 additions and 1 deletion.
    20 changes: 20 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,20 @@
    If your website has some kind of notifications system showing the user a count
    of their unread notifications or similar ([Facebook](https://facebook.com/),
    [Google+](https://plus.google.com/), [GMail](https://mail.google.com/) or so),
    as soon as your user performs an action in one window that changes the count,
    please make the change immediately propagate to all open tabs in that browser,
    without the user having to revisit / reload / click "notifications", or similar.

    This is easy to do in
    [browsers supporting `localStorage`](http://caniuse.com/#search=localStorage)
    (which is all of them released since 2009, i e IE8+),
    by subscribing to the [`storage` event](https://developer.mozilla.org/en-US/docs/Web/Events/storage),
    as demonstrated in this example.

    Try opening this page in two browser tabs or windows and click the buttons.
    The event fires on all _other_ windows accessing the same `localStorage`,
    so the update will propagate over your whole site by default, as you want.

    Your most recently hired front-end developer can pull this off single-handedly.
    At the time of posting this (September 23, 2015),
    none of the social services linked are this kind to their users.
    3 changes: 2 additions & 1 deletion notifications.js
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,8 @@ updateCount(count);
    window.addEventListener('storage', onStorageChange);

    function updateCount(n) {
    return header.textContent = document.title = title + ': ' + n;
    var t = header.textContent = document.title = title + ': ' + n;
    if (frameElement) parent.document.title = t; // for bl.ocks.org's parent frame
    }

    function getCount() {
  7. johan created this gist Sep 24, 2015.
    15 changes: 15 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,15 @@
    <!doctype html>
    <html>
    <head>
    <title>Unseen Notifications</title>
    </head>
    <body>

    <h1>Unseen Notifications</h1>

    <button id="add">Add to unseen</button>
    <button id="clr">Clear unseen</button>

    <script src="notifications.js"></script>
    </body>
    </html>
    34 changes: 34 additions & 0 deletions notifications.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    var header = document.querySelector('h1');
    var count = getCount();
    var title = document.title;

    updateCount(count);
    window.addEventListener('storage', onStorageChange);

    function updateCount(n) {
    return header.textContent = document.title = title + ': ' + n;
    }

    function getCount() {
    return JSON.parse(localStorage.unseenNotificationCount || '0');
    }

    function setCount(n) {
    localStorage.unseenNotificationCount = JSON.stringify(n || 0);
    return count = n;
    }

    function onStorageChange(e) {
    if (e.key !== 'unseenNotificationCount') return;
    var t = (new Date(e.timeStamp)).toISOString();
    var v = e.newValue;
    console.log('%s: %s = %s', t, e.key, v);
    updateCount(v);
    }

    document.body.addEventListener('click', function(e) {
    switch (e.target.id) {
    case 'clr': return updateCount(setCount(0));
    case 'add': return updateCount(setCount(1 + getCount()));
    }
    });