【特集】
HTML 5では、ドラッグ&ドロップを直接サポートするためのAPIが整備された。以前はmousedown、mousemove、mouseupを利用してドラッグ&ドロップを実現していたが、ブラウザによるネイティブサポートが実現した事で、他のアプリケーションともデータをやり取りできるようになり、コーディングも簡略化された。
HTML 5でドラッグ&ドロップを実現するための最小限の手順は以下の通りだ。
| イベント名 | イベントの通知先 | 説明 |
| dragstart | ドラッグ対象の要素 | ドラッグが開始された |
| drag | ドラッグ対象の要素 | ドラッグ中 |
| dragenter | ドラッグ中にマウスオーバーした要素 | ドラッグ操作が要素の範囲内に入った |
| dragover | ドラッグ中にマウスオーバーした要素 | ドラッグ操作が要素の範囲内を通過中 |
| dragleave | ドラッグ中にマウスオーバーした要素 | ドラッグ操作が要素の範囲内を出た |
| drop | ドロップ先の要素 | ドロップされた |
| dragend | ドラッグ対象の要素 | ドラッグが終了した |
では、この手順に則ってドラッグ&ドロップを実現したサンプルを以下に示す。以下のサンプルは、「ドラッグしてね!」と表示されているdiv要素を、その下にあるdiv要素に対してドラッグ&ドロップすることができる。ドラッグされるたびに、下のdiv要素には「Hello」という文字列が追加される。
|
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ドラッグ&ドロップのデモ</title>
<script type="text/javascript">
function init() {
var source = document.getElementById("dragme");
var dest = document.getElementById("text");
// (1) ドラッグ開始
source.addEventListener("dragstart", function(ev) {
// dataTransferオブジェクトに対し、データを追加
var dt = ev.dataTransfer;
dt.setData("text/plain", "Hello");
return true;
}, false);
// (2) ドラッグオーバー
dest.addEventListener("dragover", function(ev) {
// デフォルトの動作(ドロップの拒否)を行わない
ev.preventDefault();
return false;
}, false);
// (3) ドロップ
dest.addEventListener("drop", function(ev) {
// DataTransferオブジェクトからデータを取得
var dt = ev.dataTransfer;
var text = dt.getData("text/plain");
dest.textContent += text;
// イベントのバブリングを停止
ev.stopPropagation();
return false;
}, false);
}
</script>
</head>
<body onload="init()">
<h1>ドラッグ&ドロップのデモ</h1>
<!-- (4) draggable属性をtrueに -->
<div id="dragme" draggable="true" style="-webkit-user-drag: element; width: 200px; border: 1px solid gray;">
ドラッグしてね!
</div>
<div id="text"
style="width: 200px; height: 200px; border: 1px solid gray;"></div>
</body>
</html>
上のソースコードにおけるポイントを解説する。
(1) ドラッグが開始(dragstartイベント)された際、ドロップするデータをDataTransferオブジェクトにセット(setData()メソッド)する。DataTransferオブジェクトとは、ドラッグイベントのdataTransferプロパティから取得することができ、ドラッグ&ドロップによって持ち運ばれるデータを格納するためのオブジェクトだ。同オブジェクトのsetData()メソッドは、第1引数にデータの種別を表す文字列、第2引数にデータ自体を指定する。第1引数のデータ種別には任意の文字列を指定できるだけではなく、「text/plain」や「text/html」といったMIMEタイプも指定することができる。
(2) ドロップを受け付ける要素に対しては、dragoverイベント内で「イベントオブジェクト.preventDefault()」を呼び出す必要がある。これは、dragoverイベントのデフォルト動作が「ドロップ拒否」になっているため。このデフォルト動作を停止しないと、ドロップを受け付けることができない。
(3) ドロップされたら、DataTransferオブジェクトからデータを取得(getData()メソッド)して処理を行う。getData()の引数には、setData()時に指定したデータ種別(ここでは「text/plain」)を指定する。
(4) ドラッグ可能な要素には「draggable="true"」を指定する必要がある。またこのサンプルでは、現在のSafariやChromeでも動作するように、"-webkit-user-drag: element;"というWebkit固有のCSSプロパティを指定している。
さらにこのサンプルは、データ種別として「text/plain」というMIMEタイプを使用しているため、同MIMEタイプを解釈できる他のアプリケーションともデータのやり取りが可能だ。
ドラッグ&ドロップ処理で使用される一般的なMIMEタイプとしては以下のようなものが挙げられる。
残念ながら、OSネイティブのファイルをドラッグ&ドロップで取得するための汎用的な方法は存在しない。
ドラッグ&ドロップに関するその他のAPIを駆使すれば、ドラッグ中のイメージをカスタマイズしたり、特定の操作(コピー/移動/リンクなど)以外はドロップを受け付けないようにするなど、さらに高度な処理を実現可能だ。そうした処理を実現するため、DataTransferオブジェクトに用意されているAPIを簡単に挙げておく
| 属性/メソッド | 説明 |
| DOMString dropEffect | ドロップ操作の種別を表す。明示的に値をセットする事も可能。ドロップ先がこの種別のドロップを許可していなかったら、ドロップが受け付けられない。指定できる値(文字列)はnone、copy、link、 moveのいずれか。 |
| DOMString effectAllowed | ドロップを受け付ける操作の種別を表す。指定できる値(文字列)はnone、copy、copyLink、copyMove、link、linkMove、move、all、uninitializeのいずれか。 |
| DOMStringType types | 格納されているデータの種別を、文字列の擬似配列として返す |
| void clearData(DOMString format) | データをクリアする。引数formatを省略すると、すべてのデータがクリアされる |
| void setData(DOMString format, DOMString data) | データをセットする |
| DOMString getData(DOMString format) | データを取得する |
| void setDragImage(Element image, long x, long y) | ドラッグ中のイメージをimg要素でセットする(ブラウザによってはcanvasなども受け付けられる) |
| void addElement(Element element) | ドラッグ対象の要素を追加する |
今回は「HTML 5 - HTMLとXHTML向けのボキャブラリと関連API」から、HTML 5で新しく導入されたタグやAPIを中心にお伝えした。次回はアプリケーションキャッシュやWeb Storageなど、次世代のWebアプリケーションを実現するための各種APIを解説したいと思う。
| HTML 5アプリケーション開発について議論しよう! HTML5-Developers-jp発足 [2009/7/27] |
| "CSS3/HTML5、各ブラウザはどこまで対応?" を、確かめられる「Modernizr」 [2009/7/7] |
| 5分で把握するHTML5 - Google Developer Dayセッションリポート [2009/6/15] |
| HTML 5アプリケーション開発について議論しよう! HTML5-Developers-jp発足 [2009/7/27] |
| マイナビ、3月より書籍連動型のクリエイティブ・デザイン系セミナー開講 [12:00 2/10] |
| Linux Mint 12 KDE登場 [10:26 2/10] |
| Dell、重複排除により最大98%のデータ削減が可能なバックアップストレージを発売 [09:44 2/10] |
| 北大、「ポジトロン断層撮影法」による脳腫瘍の性質を診断する手法を開発 [09:40 2/10] |
| NICTなど、手術支援ロボット「da Vinci」の3D裸眼映像伝送実証実験を計画 [09:36 2/10] |
|
松嶋菜々子登場に「ミタ」パパ・長谷川博己パニック - 鈴木京香との熱愛は? [12:03 2/10] エンタメ |
|
【コラム】奥様はコマガール 第31回 30代既婚男性たちの妻への本音 [12:00 2/10] ライフ |
|
マイナビ、3月より書籍連動型のクリエイティブ・デザイン系セミナー開講 [12:00 2/10] エンタープライズ |
|
【レポート】CP+2012 - ビジュアルのクオリティと新しいアクセス手段を追求 - ソニー [11:52 2/10] 家電 |
|
「SBIポイント」が「Suicaポイント」とポイント交換提携サービスを開始 [11:50 2/10] ライフ |