IE10 PPB2 が提供する HTML5 のドラッグ アンド ドロップ
本記事は、マイクロソフト本社の IE チームのブログ から記事を抜粋し、翻訳したものです。
【元記事】HTML5 Drag and Drop in IE10 PPB2 (2011/7/28 1:51 AM )
ドラッグ アンド ドロップは、おそらく深く考えることなく、日常的に使用されているユーザー操作モデルです。
あるフォルダーから別のフォルダーにファイルをドラッグしたり、ドキュメントのある場所から別の場所にテキストをドラッグしたり、PowerPoint のスライドをプレゼンテーション内の別の場所にドラッグしたりといった操作が行われています。
Internet Explorer 10 Platform Preview 2 で利用可能な HTML5 のドラッグアンドドロップは、この自然でユーザーにとってなじみの深い動作を Web でも可能にします。Internet Explorer Test Drive サイトの「Magnetic Poetry」は、以前はプラグインや JavaScript ライブラリを必要としていた処理を、HTML5 のドラッグ アンド ドロップで実行可能にしたサイトの例です。
このデモの詳細な構成については、こちらのビデオを参照してください。
HTML5 以前は、JavaScript フレームワークがない場合、Web 上のドラッグ アンド ドロップ動作は部分的にしかサポートされていませんでした。HTML5 では、ドラッグ アンド ドロップをサイト内で自在に活用できます。
要素をドラッグ可能にする
特定の要素 (画像、リンク、選択したテキストなど) は既定でもドラッグ可能ですが、HTML5 では、draggable 属性を "true" に設定することで、”任意の” 要素をドラッグ可能にすることができます。
たとえば、div 要素をドラッグ可能にするには、その要素の draggable 属性を "true" に設定します。これで、div を画像と同じようにドラッグできます。Magnetic Poetry のデモの各マグネットは、draggable 属性を true に設定した span 要素です。
<span draggable="true" class="wordMagnet">HTML5</span>
要素をドラッグ可能にすると、クリックによってドラッグが開始されるようになり、ユーザーがその要素内のテキストを選択できなくなる点に注意してください。
draggable 属性の値はマークアップまたはスクリプトで設定できます。各要素には既定の draggable 状態が設定されています。画像とリンクは既定で draggable=true に設定されていますが、その他のすべての要素は既定で draggable=false となっています。
要素をドロップターゲットにする
特定の要素が既定でドラッグ可能になっているのと同じく、既定でドロップ ターゲットになっている要素もあります。このような要素として、テキスト入力ボックスと contenteditable 要素が挙げられます。ドラッグ イベントを適切に処理することによって、任意の要素をドロップ ターゲットにすることも可能です。
ドラッグイベント
ドラッグ操作を実行するときには、ドラッグしている要素と、ドラッグ時に通過する要素を考慮する必要があります。ドラッグ イベントはこれらの両方の要素で発生します。
ドラッグされる要素は次のイベントを受け取ります。
dragstart: ユーザーがドラッグを開始する
drag: ユーザーが要素を移動している
dragend: ユーザーがドラッグを終了する
ドラッグ時に通過する要素は次のイベントを受け取ります。
dragenter: ドラッグがその要素の領域に入る
dragleave: ドラッグがその要素の領域から離れる
dragover: ドラッグがその要素の領域内を移動している
最終的なイベントである drop イベントは、ユーザーがコンテンツをドロップしたときに発生します。既定でこのイベントを受け取るのは、input 要素と contenteditable 要素だけです。他の要素をドロップ ターゲットにして、ドロップ イベントを受け取るようにするには、dragenter イベントと dragover イベントで preventDefault() を呼び出す必要があります。div 要素をドロップ ターゲットにする例を以下に示します。
<div id="dropTarget">Drop Here</div>
<script>
function init() {
var dropTarget = document.getElementById("dropTarget");
dropTarget.addEventListener("dragenter", makeDrop, false);
dropTarget.addEventListener("dragover", makeDrop, false);
dropTarget.addEventListener("drop", doSomething, false);
}
function makeDrop(e) {
e.preventDefault();
}
</script>
Magnetic Poetry デモでは、マグネットをクリックしたときに (dragstart)、スクリプトによって、まず要素内でマウスがクリックされた場所が計算されます。マグネットをドロップすると (dragend)、マグネットの新しい位置が計算され、これによりドロップした位置にマグネットが移動します。
マグネットをドロップしたときに、マグネットが回転することにも注目してください。この回転の量は、マグネットの中心にどれくらい近い場所をクリックするかによって決まります。中心に近い場所をクリックした場合はほぼ水平にドロップされますが、端をクリックした場合は回転量が多くなります。この動作は、より自然なイメージを与えるためのものです。
ドラッグデータへのアクセス
マグネットを冷蔵庫上で移動する動作では、移動される要素であるマグネットだけがアクションを実行すればよく、ドラッグされる要素と、ドラッグ時に通過する要素との間でデータを交換する必要はありませんでした。しかし、その他の多くのドラッグ アンド ドロップのシナリオでは、ドラッグ コンテンツとドロップ ターゲットとの間でデータ交換が必要になります。ブロックをドラッグして正しい穴に入れるという簡単な子供向けゲームを例に考えてみましょう。穴がドロップ イベントを受け取った際、ブロックが正しい形状であるかどうかを確認するために、何がドロップされたのかを識別する必要があります。
ドラッグされる要素とドラッグ時に通過する要素の間でのデータ交換を容易にするために、ドラッグ イベントには dataTransfer オブジェクトが含まれています。dataTransfer オブジェクトは、dragstart イベントの発生時にのみデータを書き込むことができ、drop イベントの発生時には読み取り専用になります。
例に挙げた簡単な子供向けブロック ゲームのコードは次のようになります。
<div id="circle" draggable="true"></div>
<div id="triangle" draggable="true"></div>
<div id="circleHole"></div>
<div id="triangleHole"></div>
<script>
function init() {
// circle および triangle 要素を登録して、dragstart 時に setShape を呼び出す
// circleHole および triangleHole を登録して、dragenter および dragover イベントを取り消し、drop 時に checkShape を呼び出す
}
function setShape(e) {
e.dataTransfer.setData("text", this.id);
}
function checkShape(e) {
var dropped = e.dataTransfer.getData("text");
// 正しい形状かどうかを確認する...
}
</script>
ファイルのドラッグアンドドロップ
最後にもう 1 つ、HTML5 のドラッグ アンド ドロップの画期的な点は、デスクトップから Web サイトにファイルをドラッグできることです。Web サイトにファイルをドロップすると、Web サイトはファイルの内容を読み取り、サイト内でファイルを使用できます。Magnetic Poetry デモでは、この機能を使用して冷蔵庫上に小さなプレビュー画像を作成することができます。画像ファイルを冷蔵庫の上にドラッグすると、プレビュー画像が表示されます。
ファイルのドロップを受け入れるため、ページの本文には drop イベントを登録しておきます。ページは drop イベントを受け取ると、dataTransfer オブジェクトをチェックして、files 属性 (event.dataTransfer.files) に内容が含まれているかどうかを確認します。ドロップに 1 つまたは複数のファイルが含まれている場合、files 属性には FileList が含まれます。配列内の各 File は、FileReader インターフェイスを通じて読み取ることができます。Magnetic Poetry デモでは、ファイルを dataURL として読み取り、作成する新しい画像の src 属性として使用しています。このようにして、ファイルをアップロードしなくても、ユーザーがドロップした画像が Web ページに表示されます。以下のコード スニペットは、ファイルを取得して読み取る処理を示しています。
function dropHandler(event) {
var filelist = event.dataTransfer.files;
if (!filelist) return;
if (filelist.length > 0) {
var file = filelist[0];
var image = document.createElement('img');
image.src = "";
var filereader = new FileReader();
filereader.imageElt = image;
filereader.onloadend = handleReaderOnLoadEnd;
filereader.readAsDataURL(file);
}
}
function handleReaderOnLoadEnd(event) {
var image = this.imageElt;
image.src = this.result;
document.body.appendChild(image);
}
ドラッグアンドドロップのアクセシビリティに関する考慮事項
ドラッグ アンド ドロップは優れた操作モードですが、キーボードしか使用できないユーザーは、マウスでドラッグ アンド ドロップの操作を実行できないことになります。ドラッグ アンド ドロップ エクスペリエンスを作成する場合は、常に、キーボード ユーザーが同じタスクを実行できるようにする方法を考える必要があります。
また、最近 HTML5 の仕様に追加された、アイテムをドロップできるドキュメント上の領域を識別する dropzone 属性についても考慮すべき点があります。Internet Explorer では、dropzone 属性を追加した要素が自動的にドロップ ターゲットになることはなく、ドロップ ターゲットを指定するには、前述のように、ドラッグ イベントを適切に処理する必要があります。この点に注意してサイト内で dropzone 属性を使用すると、この属性を使用することを選択したすべてのアクセシビリティ ツールにドロップ ターゲットが通知されるので、ドラッグ アンド ドロップ エクスペリエンスのアクセシビリティ向上につながります。
お試しください
HTML5 のドラッグ アンド ドロップは、現在、Internet Explorer 10 Platform Preview 2 で利用できます。ぜひ、実際に使ってみてください (Magnetic Poetry デモで作成した詩を友人と共有することもできます)。
—Sharon Newman、Internet Explorer プログラム マネージャー