HTML5のドラッグ&ドロップAPI、File API、Web Storage

2012年5月8日(火)
飯島 聡(著)山田 祥寛(監修)

ファイルの内容を読み取る

FileReaderオブジェクトを利用する事で、Fileオブジェクト(ファイル)の中身を読み込む事もできます。先ほどのサンプルの一部だけ修正して、ファイル情報表示のテーブルにテキストファイルの内容を表示します。

[サンプル]テーブルに内容を表示する列を追加(HTML5_3_sample6.html)

  ・・・ ・・・
  <table>
    <thead><tr><th>名前</th><th>MIME Type</th><th>サイズ(bytes)</th><th>内容</th></tr></thead>
    <tbody id="fileInfoList"></tbody>
  </table>
 図12:「内容」を追加(クリックで拡大)

HTMLではまず表のヘッダに「内容」を追加します。

[サンプル]右の列にテキストファイルの内容を表示(HTML5_3_sample6.html)

  //FileListオブジェクトのFileの情報(名前、MIMEタイプ、サイズ(バイト))を一覧表示
  function displayFileInfo(e){
    ・・・(略) ・・・
    for(var i = 0; i < files.length; i++){
      file = files[i];
      tr = document.createElement("tr");
      ・・・(略) ・・・
      //内容表示のためのセル(td要素)をid付きで追加
      tr.innerHTML += "<td id=\"file"+i+"\"></td>";//・・・(1)
      fileInfo.appendChild(tr);
      //file.typeの/の前の内容を取得
      var fileType = file.type.split("/")[0];
      if(fileType=="text"){
        //テキストファイルの場合下記のメソッドを呼び出す
        writeFileContents(file,"file"+i);//・・・(2)
      }
    }
  }
  //textファイルの内容を読み込んでテキストエリアに表示
  function writeFileContents(file,tdid){
    //FileReaderオブジェクトを作成
    var reader = new FileReader();//・・・(3)
    //正常に読み込み完了した場合に以下のハンドラが実行される
    reader.onload = function(ev){//・・・(4)
      //出力するtd要素を取得
      var td = document.getElementById(tdid);
      //テキストエリアを作成
      var ta = document.createElement("textarea");
      ta.rows = 5;
      ta.cols = 50;
      //resultプロパティに読み取ったテキストが格納されているので
      //取得してテキストエリアに表示
      ta.value = ev.target.result;//・・・(5)
      //テキストエリアをtdの子要素に追加
      td.appendChild(ta);
    };
    //エラーが起きた場合に場合に以下のハンドラが実行される
    reader.onerror = function(ev){//・・・(6)
      var td = document.getElementById(tdid);
      td.innerHTML = "エラー(code: "+ev.target.error.code+")";
    };
    //textファイル読み込みの開始
    reader.readAsText(file);//・・・(7)
  }

サンプルのスクリプトでは以下の事を行っています。

  1. テーブル行を表すtr要素に新しいセルtd要素を、idを付けて追加(idは後で対応するテキストファイルの内容列にテキストフィールドを追加するために使用)
  2. file.typeの"/"より前の文字列がtextの場合、fileとidを引数として下にあるメソッドの呼び出し
  3. FileReaderを生成
  4. onloadに読み込み完了時に呼び出すハンドラを設定(ファイル内容を表示するテキストエリアを生成してtdに追加)
  5. テキストエリアのvalueにテキストファイルの内容(result)をセット
  6. onerrorにエラー発生時に呼び出すハンドラを設定
  7. テキストファイルを読み込むメソッド(readAsText)の呼び出し

readAsTextメソッドを呼び出した後、読み込みが正常に完了すると、onloadに設定したハンドラが呼び出されます。readerのresultプロパティにテキストファイルの内容が文字列として入っています。サンプルでは、その内容をテキストエリアに表示しています。

読み込みでエラーが起きた場合に場合にはonerrorに設定したハンドラが実行されます。サンプルではエラーコードを表示しています。

 図13:テキストファイルの内容を表示(クリックで拡大)

ブラウザで利用できるKey-Value型のストレージ - Web Storage

Web Storageは、キー/値のセットをブラウザに保存するしくみです。クッキーとよく似ていますが、以下の点で異なります。

表4:Web Storageとクッキーの比較

特徴 クッキー Web Storage
容量上限 4Kbytes 5Mbytes
期限 保存時に設定した期限、未設定ならブラウザ終了まで ウィンドウ終了までのものと永続的なものがある
送信 リクエストの度に送信 必要な時に送信
ウィンドウ間共有 共有される 共有されないものとされるものがある

また、Web Storageには、sessionStorageとlocalStorageという2種類のストレージが用意されています。両者の違いについては、サンプルを動かしながら、別途確認していきます。

Web Storageの基本例

それでは早速、具体的な例を見てみましょう。以下は、テキストエリアに入力されたデータを保存しない場合と、sessionStorageとlocalStorageにそれぞれデータを保存する場合とを比較するサンプルです。上から2番目のテキストエリアにはsessionStorageを、3番目のテキストエリアにはlocalStorageを対応させてデータの保存を行います。

[サンプル]テキストエリアの内容をWeb Storageに保存、復元(HTML5_3_sample7.html)

  ・・・(JavaScript部分)・・・
  //ウィンドウのloadイベントに下記の初期化メソッドinitを関連付ける
  window.addEventListener("load",init,true);
  //初期化メソッド各要素にイベントハンドラを設定する
  function init(){
    var ta2= document.getElementById("ta2");
    var ta3= document.getElementById("ta3");
    //changeイベントのタイミングでwebStorage保存のメソッドを呼ぶ
    ta2.addEventListener("change",saveToSessionStorage,true);//・・・(1)
    ta3.addEventListener("change",saveToLocalStorage,true);//・・・(2)
    //sessionStorageから読み込む
    var savedText = window.sessionStorage["savedText"];//・・・(3)
    if(savedText){
      ta2.value = savedText;
    }
    //localStorageから読み込む
    savedText = window.localStorage["savedText"];//・・・(4)
    if(savedText){
      ta3.value = savedText;
    }
  }
  //sessionStorageに保存する
  function saveToSessionStorage(e){
    window.sessionStorage["savedText"] = e.target.value;//・・・(5)
  }
  //localStorageに保存する
  function saveToLocalStorage(e){
    window.localStorage["savedText"] = e.target.value;//・・・(6)
  }
  
  ・・・ (HTML部分) ・・・
  <h1>Web Storage サンプル</h1>
  <form name="form1">
    <h3>普通のテキストエリア</h3>
    <textarea rows="10" cols="100" id="ta1"></textarea>
    <h3>sessionStorageに保存</h3>
    <textarea rows="10" cols="100" id="ta2"></textarea>
    <h3>localStorageに保存</h3>
    <textarea rows="10" cols="100" id="ta3"></textarea>
  </form>

Web Storage(ストレージ)にはwindowオブジェクトのsessionStorage、localStorageプロパティでアクセスできます。

いずれかのストレージを取得できたら、後はハッシュと同じ要領で、「xxxxxStorage["キー名"] = 値;」の形式で値を出し入れできます。

サンプルでは、ページロード時にストレージから値を取り出してテキストエリアにセットし、テキストエリアに変更があったらストレージに書き戻しています。

  1. 2番目のテキストエリアのchangeイベントハンドラとして、sessionStorageに保存するメソッドを設定
  2. 3番目のテキストエリアのchangeイベントハンドラとして、localStorageに保存するメソッドを設定
  3. sessionStorageからキー"savedText"に対する値を読み込む
  4. localStorageからキー"savedText"に対する値を読み込む
  5. sessionStorageにキー"savedText"と2番目のテキストエリアの内容を保存する
  6. localStorageにキー"savedText"と3番目のテキストエリアの内容を保存する

以下は、サンプルを実行した結果です。

 図14:それぞれに値を入力(クリックで拡大)

値を入力して、ブラウザの更新ボタンを押します。

 図15:storageに値が保存されている(クリックで拡大)

ストレージにデータを保存している2〜3番目のテキストエリアでは文字列が維持されている事が確認できます。

続いて、ブラウザをいったん閉じて、再度サンプルを起動してみましょう。

 図16:localStorageのみ値が保存されている(クリックで拡大)

今度は、一番下のlocalStorageのところだけ値が表示されました。sessionStorageに保存したデータは、そのページを閉じると消えてしまいます。localStorageのみ値が保存されています。

値をそれぞれ入力して、別のウィンドウで、同じファイルを開きます。

 図17:localStorageのみ値が共有される(クリックで拡大)

同じくsessionStorageの値は消えてしまいます。sessionStorageに保存したデータは、異なるウィンドウ間で値の共有はされないからです。localStorageに保存したデータは異なるウィンドウ間でも共有できます。

sessionStorage/localStorageの主なメンバ

sessionStorageもlocalStorageもStorageオブジェクトの派生オブジェクトで、共通のメンバにアクセスできます。getItemやsetItemは、既に見たようにハッシュ形式で代替する事もできます。

表 Storageオブジェクトのメンバ

メンバの種類 メンバ名 説明
プロパティ length エントリの数
メソッド key(index) 指定indexにあるキーを取得
getItem(key) キーに対応した値
setItem(key,value) キーと値をセット
removeItem(key) 指定したキーのエントリを削除
clear() 全てのエントリを削除

まとめ

今回は、Webアプリケーションの枠組みを超えたHTML5の新機能を説明しました。これらの機能を利用する事で、HTML関連技術を使用して、サーバー処理を必要としないクライアント型アプリケーションを作成する事もできます。

次回はHTML5の新機能の中でも、ネットワークに関わる機能について説明します。

【参考文献】

<リンク先最終アクセス:2012.04>

  • ドラッグ&ドロップAPI、File API、Web StorageのHTMLサンプル

著者
飯島 聡(著)山田 祥寛(監修)
WINGSプロジェクト

有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表:山田祥寛)。おもな活動は、Web開発分野の書籍/雑誌/Web記事の執筆。ほかに海外記事の翻訳、講演なども幅広く手がける。2011年3月時点での登録メンバは36名で、現在もプロジェクトメンバーを募集中。執筆に興味のある方は、どしどしご応募頂きたい。著書多数。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています