読者です 読者をやめる 読者になる 読者になる

望月いちろうのREADME.md

書き溜めておいた技術記事や旅行記のバックアップです。

ブラウザのフォームの入力値を一時的に保存したいとき - WebStorageを利用する

HTML5 JavaScript

こんにちは望月です

現在、簡単なCMSを自作しています。それは昔からあるWordPressなどのオープンソースCMSに持っている不満を解消したいと思っているからです。

まず最初に不満に思っているのは、文章を作成途中にブラウザがクラッシュしてしまうと、文章がすべて消えてしまうことがあります。

僕は昔、結構長い文章を書いていたら、ブラウザが落ちてしまい、編集途中のデータがすべて消えてしまい。がっかりした経験があります。

実はHTML5に対応したブラウザではローカルにデータをキャッシュすることができます。このWeb Storageという機能の特徴として

  • Key-valueストアとしての基本的な機能を兼ね備えている。
  • 最大で4~5MBのデータを扱うことができる。
  • 対応しているデータ形式は文字列のみ
  • ドメインごとにストレージが割り当てられる。少なくとも他のサイトからデータを見られることはない。

もちろん、このKey・Valueストアライクな機能は、あくまで、簡易的なものにすぎません。

これについてはHTML5 ROCKSのサイトに

https://www.html5rocks.com/en/features/storage 以下のような記述があります。

ブラウザのローカルストレージを使用する理由は複数あり。まず、ユーザーがオフラインのときにアプリを動作させることができ、そして、ネットワークが再び接続されると、データを同期させることができます。第二に、それはパフォーマンスの向上です。ユーザーがあなたのサイトをクリックするとすぐに、それが再度ダウンロードされるのを待つことなく、大きなサイズのデータを表示することができます。第3に、サーバーを必要としないアプリケーションを簡単に作成できます。もちろん、データはブラウザからしかアクセスできないため、それほど重要ではないデータのキャッシュにのみ使用してください。

翻訳:望月いちろう

また同じページには各ブラウザの対応状況が追記してあります。

f:id:mochizuki_p:20161112213532p:plain

ここで紹介するWeb Storageは相当古いブラウザでなければ対応されています。

そして単純なキー・バリューストアよりもより高度なストレージ機能である。IndexedDBやWeb SQL Databaseもありますが、ここでは省略します。

さてそれでは今回の本題である。WebStorageの機能について簡単なデモを実行します。

WebStorageの仕様については公式の規格を参照してください。 https://html.spec.whatwg.org/multipage/webstorage.html

localStorageを利用する。

今回利用するのはlocalStorageです。WebStorageにはこれの他に、sessionStorageがありますが、今回の用途ではlocalStorageを利用すべきでしょう。

localStorageの使い方

localStorageの基本的なデータ構造はJSONにとても似ています。というか、実用上はJSONそのものだと思っていただいても問題ありません。

繰り返しますが、localStorageはキー・バリューストアです。つまり、データと対になる名前をつける必要があります。

またlocalStorageはグローバル変数ですので、スコープを特に考慮する必要はありません。

データの保存

setItem()を利用します。最初の引数にキーを指定して、2番目の引数に値を指定します。 当然ですが、キーはユニークな値である必要があります。

var draft = document.getElementById("textarea").value;
localStorage.setItem("draft",draft);

ほかにオブジェクト形式でもデータの保存が可能

localStorage["draft"] = draft;
localStorage.draft = draft;

データの更新

setItem()で更新したいデータのキーで更新後のデータを上書きすればよい

var draft = document.getElementById("textarea").value;
localStorage.setItem("draft",draft);

ほかにオブジェクト形式でもデータの更新が可能

localStorage["draft"] = draft;
localStorage.draft = draft;

データの削除

removeItem()を利用します。最初の引数にキーを指定して、2番目の引数に値を指定します。 当然ですが、キーはユニークな値である必要があります。

localStorage.removeItem("draft")

ストレージを丸ごと削除する場合

もちろん該当のドメインのみです。

localStorage.clear()

ちょっとした工夫

ファイルをJSON形式で保存する。

そのままJSONを保存することができないので文字列化してから保存

デモ

さて簡単なテキストエディタを実装してみます。突然ブラウザが落ちても、ちゃんと編集した内容がキャッシュされていることを確認します。

<!DOCTYPE html>
<html>
  <head>
    <title>WebStorage Demo</title>
    <meta charset="utf-8">
  </head>
  <body>
    <textarea id="draft">
    </textarea>
    <button id="b">ローカルストレージの内容を表示</button>
    <script type="text/javascript">
        
    var draft = document.getElementById("draft");
    
    draft.addEventListener("change",function(e){
                           console.log(e.target.value);
                           console.log(draft.value);
                           localStorage.setItem("draft",draft.value);
                           });
                           
    var b = document.getElementById("b")
    
    b.addEventListener("click",function(){
                       alert(localStorage["draft"]);
                       });
    </script>
  </body>
</html>


このHTMLファイルを保存してテキストエリアに適当なメッセージを入力します。

f:id:mochizuki_p:20161112212400p:plain そしてそのままブラウザを閉じて、また開いてください。

f:id:mochizuki_p:20161112212422p:plain

本来であればこのときにテキストエリアに入力した内容は消えてしまうはずです。

しかし、「ローカルストレージの内容を表示」のボタンを押すと、

f:id:mochizuki_p:20161112212435p:plain

データが残っていました!

この機能を利用すれば今回の目的であった。編集途中のテキストの保護機能は簡単に実装できますね。