Drag and DropとFile APIを試す

HTML5のDrag and Drop APIとFile APIを試してみました。

Drag And Drop API

  1. HTML上の要素のドラッグアンドドロップをサポート
  2. File APIとの連携でデスクトップからのドラッグアンドドロップをサポート

1番はHTML5でなくてもjQuery等を用いれば実現可能ですので、File APIとの連携を試します。

jQueryでFile APIを使うために以下のおまじないを実行します。

jQuery.event.props.push('dataTransfer');

DropイベントとFile APIとの連携にはevent.dataTransferプロパティを使いますが、jQueryのイベントオブジェクトにはdataTransferが存在しません。このおまじないで、jQueryのeventオブジェクトにブラウザネイティブのeventオブジェクトからコピーしてセットされるようになります。

    $("html").bind("drop", function(event){
        event.stopPropagation();
        event.preventDefault();    
    
        var dt = event.dataTransfer;
        var file = dt.files[0];
        
	viewFileInfo(file);
	viewFileContent(file);
    }).bind("dragenter dragover", false);

dataTransfar.filesプロパティにファイルの情報が入っています。配列になっており複数ファイルのドラッグアンドドロップに対応していることが分かりますが、ここでは一つ目のファイルだけを処理します。

jQueryのbindでドロップイベントを拾います。ドラッグ時に色を変える、受付可能なファイルかどうか判定してカーソルを変えるといった効果を出したいならばdragenter dragover dragend等のイベントでセットします。ここでは何もしません。

    function viewFileInfo(file) {
        if (file) {
            $("#fileName").text(file.name);
            $("#fileSize").text(file.size);
            $("#fileType").text(file.type);
        }
    }

ファイル名、ファイルサイズ、ファイルタイプの情報にアクセスできます。

    function viewFileContent(file) {
    	if (!window.FileReader) {
    		$("#textViewer").text("File読み込みをサポートしていません")
    		return;
    	}
    
        if (file.type.match(/text/)) {
            var fr = new FileReader()
            fr.onload = function(event){
                $("#textViewer").text(event.target.result);
            };
            fr.readAsText(file, "utf-8");
        }
    }

FileReaderオブジェクトを使うと、ファイルの中身にアクセスできます。FirefoxChromeでは使えますが、Safariには実装されていないようです。ファイルデータアクセス成功時にloadコールバックを呼び出すというイベント駆動型の処理方式になっています。readAsTextの他に以下のデータ取得メソッドがあります。

  • readAsBinaryString()
  • readAsDataURL()
  • readAsText()
  • readAsArrayBuffer()

ファイル読み込みのイベントは以下になります

  • loadstart 読み込み開始
  • progress 読み込み中 (progess.loaded/progress.total)
  • abort 読み込みが中断された(abortメソッドが呼ばれた場合)
  • error エラー発生時、ファイルが読めない等
  • load ロード完了.
  • loadend 処理完了(失敗、成功どちらでも呼ばれる)

XMLHttpRequestのようなイベント駆動型の処理に慣れていれば難しくありません。