HTML5 Drag and Drop API についてのまとめ 〜その1 概要〜

UIとして

例えばどこかのサイトでメモしておきたい画像があったとして、
それを自分のオンラインストレージに保持したいというシーンがあったとする。
これまでは対象の画像を右クリックして画像のURLをコピー。
そしてアプリ上に入力フォームを表示する操作の後、先程のURLを入力して決定ボタンを押す。
といった操作によって対象の画像をメモするフローが多数を占めているかと思う。
この操作は大きく見ると大体6ステップのユーザ操作が必要となる。
もしこの操作を Drag and Drop により実装すると、対象画像を指定領域にドロップする。
以上の操作で行うことが出来る。


という事で効果的なUIのためにも、新しいアプリの可能性のためにも、Drag and Drop API は素敵。
< みんな知ってる

実装

まずはdrop領域に対して以下のイベントを付与する。

dropを実現する最小セットとして何故 dragover も指定する必要があるのかという理由については、
dragover は drop をネガティブにする設定がデフォルトであって、これを解除する必要があるから。
drop を指定するということはそれを目的としているのだから、この default 設定は逆であった方が良いと思うが、
そういう仕様らしいので仕方が無い。

$(function(){

    // drop area
    var _trgt = document.getElementById('drop領域の要素ID');

    // drop handle
    _trgt.addEventListener(
              'drop'
             ,function(event){
                  stopBubble(event);
                  dropHandle(event);
              }
             ,false
          )
    ;

    // dragover handle
    _trgt.addEventListener(
              'dragover'
             ,function(event){
                  stopBubble(event);
                  return false;
              }
             ,false
          )
    ;

});

// デフォルトのイベント抑制
function stopBubble (e) {
    e.stopPropagation();
    e.preventDefault();
}

// 実際のdrop処理
function dropHandle (e) {
    hogehoge
}

jQuery利用

Dropデータ

上記コードの dropHandle に渡される引数 e を firebug とかで表示すると色々な情報がある。

dropデータのタイプ

e.dataTransfer が処理の中心になってくるが、この中の types プロパティーにファイルの種別が入っている。
Dropデータ種別の判定に必要そうなので調べてみた限りの情報を表にする(以下のように取得できる)

e.dataTransfer.getData('text/plain')

Drop対象 : text
とりあえず text/plain のデータを取得すればDropした文字列がブラウザ間でも取得できる。

キー 内容 別ブラウザ(ChromeからDrop)
text/_moz_htmlcontext ??? 取れなかった
text/_moz_htmlinfo ??? 取れなかった
text/html ??? ???
text/plain Drop文字列 Drop文字列


Drop対象 : image
これも text/plain のデータを取得すればDropした画像URIがブラウザ間でも取得できる。
text/html に関してはブラウザ間でDropすると文字化けたえらいものが取れた。デコードとかで使えるのか不明。

キー 内容 別ブラウザ(ChromeからDrop)
text/x-moz-url imageのURL imageのURL
text/x-moz-url-data imageのURL 取れなかった
text/x-moz-url-desc imageのURL 取れなかった
text/uri-list imageのURL 取れなかった
text/_moz_htmlcontext ??? 取れなかった
text/_moz_htmlinfo ??? 取れなかった
text/html Dropした画像をimgタグとして返却 文字化けた文字列
text/plain imageのURL imageのURL
application/x-moz-nativeimage 取れなかった
application/x-moz-file-promise 取れなかった
application/x-moz-file-promise-url imageのURL 取れなかった
application/x-moz-file-promise-dest-filename 画像名 取れなかった
Files 取れなかった


Drop対象 : url
text/x-moz-url を利用するとページのタイトルも取得できる。
ただ基本は text/plain で取得しないとブラウザ依存する。

キー 内容 別ブラウザ(ChromeからDrop)
text/x-moz-url URL \n ページタイトル URL \n ページタイトル
text/uri-list URL 取れなかった
text/plain URL URL
text/html URLでリンクhtmlにしたものを返す 取れなかった


Drop対象 : ローカルファイル
ローカルファイルのDrop情報は、別途 e.dataTransfer.files で取得する。

キー 内容
application/x-moz-file
text/x-moz-url ローカルURI
Files
使えそうなプロパティ
   e.dataTransfer
       .files
       .types
    .currentTarget         : drop領域要素
    .explicitriginalTarget : drop領域要素(何が違うの?)
    .originalTarget        : drop領域要素(何が違うの?)
    .target                : drop領域要素(何が違うの?)
    .timeStamp             : timestamp
    .altKey                : altkeyプレス
    .shiftKey              : shiftkeyプレス

結論

んー、ちゃんと仕様を確認しよう。。

dataTransfer まわりまとめよう