Serviceworkerでオフライン表示できたのはよいが、オフライン状態かどうかユーザーに一応知らせたいとき

## 発端
[以前書いた記事](https://qiita.com/yhrym/private/f31669d48688d32155b4)紹介しましたが、Serviceworker(Workbox)によってオフライン状態でもページが表示できるようになりました。

しかし、オフライン状態での表示 = キャッシュの表示であるため、表示されている情報が古い可能性があります。
そこで「オフライン状態でページを表示していますよ」オンラインに復帰したら「ページ更新した方が良いですよ」というアラートを表示したく思いました。

## やりたいこと（イベント発火のタイミングと表示文言の整理）
- オンライン⇒オフライン
    - アラート「オフラインでページを読み込んでいます。ページの情報が古い可能性があります。」
    - テキスト「オフラインでページを読み込んでいます。ページの情報が古い可能性があります。」
- オフライン環境での更新
    - アラート「オフラインでページを更新しています。ページの情報が古い可能性があります。」
    - テキスト「オフラインでページを読み込んでいます。ページの情報が古い可能性があります。」
- オフライン⇒オンライン
    - テキスト「ページの情報が古い可能性があります。ページを更新してください。」
- オンライン環境での更新
    - もし上記テキストがあれば、削除

## 実装
Javascriptでオフラインになった時、オンラインになった時に発火するイベントがあるようなのでそれを使います。
> 参考 [Online and offline events](https://developer.mozilla.org/ja/docs/Web/API/NavigatorOnLine/Online_and_offline_events)

```javascript:networkStatus.js
  const offlineFired = 'オフラインでページを読み込んでいます。ページの情報が古い可能性があります。',
    onlineFired = 'ページの情報が古い可能性があります。ページを更新してください。';

  window.addEventListener("offline", function (e) {
    // オンライン⇒オフライン発火
    console.log("offline fired");
    alert(offlineFired);
    if ($('.onlineAttn').length) {
      $('.onlineAttn').remove();
    }
    if (!$('.offlineAttn').length) {
      $('入れ込みたい位置の要素を指定').after('<p class="offlineAttn" style="color: red; padding: 15px; border: 1px solid; margin: 0 24px 15px;">' + offlineFired + '</p>');
    }
  });
  window.addEventListener("online", function (e) {
    // オフライン⇒オンライン発火
    console.log("online fired");
    if ($('.offlineAttn').length) {
      $('.offlineAttn').remove();
      $('入れ込みたい位置の要素を指定').after('<p class="onlineAttn" style="color: red; padding: 15px; border: 1px solid; margin: 0 24px 15px;">' + onlineFired + '</p>')
    }
  });
```

オンライン⇒オフラインとオフライン⇒オンラインのイベントは対応できました。

オフライン環境での更新とオンライン環境での更新イベントを追加します。
> 参考　[window.navigator.onLine](https://developer.mozilla.org/ja/docs/Web/API/NavigatorOnLine/onLine)

```javascript:networkStatus.js
const offlineUpdate = 'オフラインでページを更新しています。ページの情報が古い可能性があります。';

if (navigator.onLine) {
    // オンライン環境での更新
    console.log('online status');
    if ($('.onlineAttn').length) {
      $('.onlineAttn').remove();
    }
    if ($('.offlineAttn').length) {
      $('.offlineAttn').remove();
    }
  } else {
    // オフライン環境での更新
    console.log('offline status');
    alert(offlineUpdate);
    if (!$('.offlineAttn').length) {
      $('入れ込みたい位置の要素を指定').after('<p class="offlineAttn" style="color: red; padding: 15px; border: 1px solid; margin: 0 24px 15px;">' + offlineFired + '</p>');
    }
  }
```

上記をまとめて関数にし、Serviceworkerが動いているときに呼び出すように記述します。

```javascript:networkStatus.js

  window.addEventListener('load', function () {
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register("sw.js")
        .then(function (registration) {
          console.log("sw registed.");
        }).catch(function (error) {
          console.warn("sw error.", error);
        });
      offlineEvent()
    }
  });

function offlineEvent() {
  const offlineFired = 'オフラインでページを読み込んでいます。ページの情報が古い可能性があります。',
    offlineUpdate = 'オフラインでページを更新しています。ページの情報が古い可能性があります。',
    onlineFired = 'ページの情報が古い可能性があります。ページを更新してください。';
  window.addEventListener("offline", function (e) {
    // オンライン⇒オフライン発火
    console.log("offline fired");
    alert(offlineFired);
    if ($('.onlineAttn').length) {
      $('.onlineAttn').remove();
    }
    if (!$('.offlineAttn').length) {
      $('#bnrSection1').after('<p class="offlineAttn" style="color: red; padding: 15px; border: 1px solid; margin: 0 24px 15px;">' + offlineFired + '</p>');
    }
  });
  window.addEventListener("online", function (e) {
    // オフライン⇒オンライン発火
    console.log("online fired");
    if ($('.offlineAttn').length) {
      $('.offlineAttn').remove();
      $('#bnrSection1').after('<p class="onlineAttn" style="color: red; padding: 15px; border: 1px solid; margin: 0 24px 15px;">' + onlineFired + '</p>')
    }
  });

  if (navigator.onLine) {
    // オンライン環境での更新
    console.log('online status');
    if ($('.onlineAttn').length) {
      $('.onlineAttn').remove();
    }
    if ($('.offlineAttn').length) {
      $('.offlineAttn').remove();
    }
  } else {
    // オフライン環境での更新
    console.log('offline status');
    alert(offlineUpdate);
    if (!$('.offlineAttn').length) {
      $('#bnrSection1').after('<p class="offlineAttn" style="color: red; padding: 15px; border: 1px solid; margin: 0 24px 15px;">' + offlineFired + '</p>');
    }
  }
}

```

実装できました。

アラート
<img width="375" alt="IMG-0171.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271161/09196d17-f678-7c9c-c512-1f0fe46b7ca9.jpeg">


テキスト
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271161/ceb44b47-9a52-2770-67a1-d895e8fd662b.png" width="400">






## 参考
- [Online and offline events](https://developer.mozilla.org/ja/docs/Web/API/NavigatorOnLine/Online_and_offline_events)
- [window.navigator.onLine](https://developer.mozilla.org/ja/docs/Web/API/NavigatorOnLine/onLine)