Firefox 3.1 の新しいドラッグ&ドロップ API の基本的な使い方 (その3~ドロップ処理)

その2~ドラッグ処理から引き続き、ドラッグ元をドロップ先へドロップ可能にするための処理と、実際にドロップしたときの処理を追加する。

ドロップ先へのドロップを可能にする

ドロップ先の要素では、テキストボックス (html:input 要素や xul:textbox 要素) などを除き、通常はいかなる形式の転送データでもドロップ不可となっている。ドロップ可能にするには、 dragenter と dragover の2つのイベントハンドラで event.preventDefault() を呼び出す。

はじめに、転送データの形式によらず常にドロップ可能にするには、 handleDropEvents 関数にて以下のような処理を追加する。

        case "dragenter": 
        case "dragover": 
            event.preventDefault();
            break;

別の書き方として、 XUL / HTML のイベントハンドラ側で ondragenter=”return false;” のようにする方法もある。

実際は特定の転送データ形式、例えばリンクのドロップのみを可能にする場合が多いので、 dragenter と dragover の2つのイベントハンドラで転送データの形式を調べ、条件付きで event.preventDefault() を呼び出すようにする。

転送データの形式を調べるには、 DataTransfer オブジェクトの types プロパティを使用する。
ひとまずは、 dragenter と dragover イベント発生時に転送データに含まれるすべての形式を列挙してみる。

        case "dragenter": 
        case "dragover": 
            for (var i = 0; i < event.dataTransfer.types.length; i++) {
                dump("    " + event.dataTransfer.types.item(i) + "
");
            }
            break;

DataTransfer の types プロパティに特定のデータ形式が含まれるかどうかは、以下のように contains メソッドを使用すると良い。

        case "dragenter": 
        case "dragover": 
            if (event.dataTransfer.types.contains("text/url-list") || 
                event.dataTransfer.types.contains("text/plain"))
                event.preventDefault();
            break;

動作確認 (1)

ドラッグ元をドラッグし、マウスの右クリックを放さずにドロップ先の枠内へ入ったり出たりすると dragenter, dragover, dragleave の3つのイベントが発生することを確認してください。
なお、 XUL / HTML をブラウザタブで開いている場合、マウスの右クリックを放してドロップすると、ブラウザタブ側でドロップイベントが発生して URL を開く動作となります。

ドロップされたデータを取得する

次に、 drop イベント発生時にドロップされた転送データを取得する処理を追加する。
ドロップされた転送データを取得するには、まず dragenter, dragover イベントハンドラでやったように DataTransfer オブジェクトの types プロパティから転送データに目的の形式が含まれることをチェックした上で、DataTransfer オブジェクトの getData メソッドで指定した形式の転送データを取得する。
なお、下記のサンプルコードでは、 XUL / HTML をブラウザタブで開いている場合を考慮し、 event.preventDefault() を呼び出して、ブラウザタブ側でドロップイベントが発生するのを阻止している。

        case "drop": 
            event.preventDefault();
            var data = null;
            if (event.dataTransfer.types.contains("text/url-list"))
                data = event.dataTransfer.getData("text/url-list");
            else if (event.dataTransfer.types.contains("text/plain"))
                data = event.dataTransfer.getData("text/plain");
            alert("Dropped URL: " + data);
            break;

以下のように、あらかじめドロップ可能なデータ形式を配列で定義しておいたほうが見通しの良いソースコードとなるかもしれない。

        case "drop": 
            event.preventDefault();
            var data = null;
            var supportedTypes = ["text/url-list", "text/plain"];
            for each (type in supportedTypes) {
                if (event.dataTransfer.types.contains(type)) {
                    data = event.dataTransfer.getData(type);
                    break;
                }
            }
            alert("Dropped URL: " + data);
            break;

動作確認 (2)

ドラッグ元をドラッグしてドロップ先へドロップすると drop イベントが発生することを確認してください。
また、ドロップされたURLがメッセージボックスで表示されることを確認してください。

参考

Drag Operations – MDC

関連記事

Firefox 3.1 の新しいドラッグ&ドロップ API の基本的な使い方 (その1~イベントハンドラの追加)
Firefox 3.1 の新しいドラッグ&ドロップ API の基本的な使い方 (その2~ドラッグ処理)
Firefox 3.1 の新しいドラッグ&ドロップ API の基本的な使い方 (その3~ドロップ処理)

TOP

TOP