トップページ  > HTML5のAPI、および、関連仕様  > ドラッグ&ドロップ

★HTML5のAPI、および、関連仕様

ドラッグ&ドロップ
Firefox3Firefox4 Google Chrome6(-webkit-) Safari5(-webkit-)
広告

■ドラッグ&ドロップとは

ドラッグ&ドロップとは、ウェブページ内の要素やローカル環境に保存されたファイルなどのデータを、 マウスで引きずるように移動させて他の場所に置く操作のことです。 HTML5以前にも、mousedownやmouseupなどのイベントで実現することはできましたが、 HTML5ではドラッグ&ドロップ専用の新しいイベントや新しいメソッド・属性が追加されています。

ドラッグ&ドロップを理解するには、ドラッグ操作とドロップ操作を分けて考えると理解しやすいでしょう。 ドラッグ操作は要素などのデータをマウスでつかんで引きずるように動かすこと、 ドロップ操作はその動かしたデータをドロップ先の要素内に配置することです。

とにかくサンプルを見てみる

■HTML側では、ドラッグする要素にdraggable属性を指定する

HTML側では、ドラッグする要素にdraggable属性を指定します。 draggable属性の値には、true・false・値なしのいずれかを指定します。 値を指定しない場合にはデフォルト動作となります。

draggable="true"
要素をドラッグ可能にする
draggable="false"
要素をドラッグ不可にする
値なし
その要素のデフォルト動作となる

href属性が指定されたa要素、および、src属性が指定されたimg要素は、デフォルトでドラッグ可となっています。 それ以外の要素は、デフォルトではドラッグ不可です。

HTMLソース

<div id="apple" draggable="true">りんご</div>

■ドロップ先の要素にdropzone属性を指定する

ドロップ先の要素にはdropzone属性を指定することになっています。

ただし、現在のところdropzone属性をサポートしているブラウザはまだ無い(?)ようなので、 また、dropzone属性を使用しなくても一部ブラウザでドラッグ&ドロップ機能を実現できるので、 このページで紹介するサンプルではひとまずdropzone属性を指定していません。

dropzone="copy"
ドラッグされるデータのコピーがドロップされる
dropzone="move"
ドラッグされるデータが移動してドロップされる
dropzone="link"
ドラッグされるデータ元へのリンクがドロップされる

■JavaScript側では、DataTransferオブジェクトでドラッグデータをドロップ先へ受け渡す

JavaScript側では、ドラッグ開始時にDataTransferというオブジェクトにドラッグするデータをセットしておき、 ドロップ時にそのデータを取り出して、ドラッグデータをドロップ先へ受け渡すことでドラッグ&ドロップを実現します。

この際、データのセットに使用するのがsetData()メソッド、 データの取得に使用するのがgetData()メソッドです。

dataTransfer . setData(format, data) …… データをセットする
data = dataTransfer . getData(format) …… データを取得する

ドラッグ&ドロップのメソッド・属性の一覧

■HTML5のドラッグ&ドロップで定義されている7つのイベント

ユーザーによるドラッグ操作やドロップ操作は、以下の7つのイベントで取得します。 それぞれのイベント発生時におけるドラッグデータ、および、 ドロップ先の要素の挙動をJavaScriptで制御してやることで、ドラッグ&ドロップ機能を実現します。

イベント名 イベントが発生するタイミング デフォルト動作
dragstart ドラッグ開始時 ドラッグを開始する
drag ドラッグが継続している間 ドラッグを継続する
dragenter ドラッグ要素がドロップ要素に入った時 ユーザーによるドロップ操作を拒否
dragleave ドラッグ要素がドロップ要素から出た時 何もしない
dragover ドラッグ要素がドロップ要素に重なっている間 現在のドラッグ操作をリセットする
drop ドロップ時 (場合による)
dragend ドラッグ終了時 (場合による)

■ドラッグ操作の概要

ドラッグ操作では、ドラッグするデータをDataTransferオブジェクトにセットすることで、ドロップ先に受け渡すことのできる状態にします。

JavaScriptソース

/***** ドラッグ開始時の処理 *****/
function f_dragstart(event){
  //ドラッグするデータのid名をDataTransferオブジェクトにセット
  event.dataTransfer.setData("text", event.target.id);
}

■ドロップ操作の概要

ドロップ操作では、DataTransferオブジェクトにセットされているデータを取り出して、ドロップ先にドラッグデータを追加します。

ドロップ先の要素は、デフォルトではユーザーによるドロップ操作を受け付けない仕様になっています。 そのため、ドロップを受け付けるように、 dragenterイベントとdragoverイベントのデフォルトアクションをキャンセルしてやる必要があります。

JavaScriptソース

/***** ドラッグ要素がドロップ要素に重なっている間の処理 *****/
function f_dragover(event){
  //dragoverイベントをキャンセルして、ドロップ先の要素がドロップを受け付けるようにする
  event.preventDefault();
}

/***** ドロップ時の処理 *****/
function f_drop(event){
  //ドラッグされたデータのid名をDataTransferオブジェクトから取得
  var id_name = event.dataTransfer.getData("text");
  //id名からドラッグされた要素を取得
  var drag_elm =document.getElementById(id_name);
  //ドロップ先にドラッグされた要素を追加
  event.currentTarget.appendChild(drag_elm);
  //エラー回避のため、ドロップ処理の最後にdropイベントをキャンセルしておく
  event.preventDefault();
}

■webkit系ブラウザでドラッグ&ドロップを動かす

Google Chrome・Safariなどのwebkit系ブラウザでは、CSSに以下の指定を追加してやると、 ドラッグ&ドロップを動かすことができます。

CSSソース

ドロップ先の要素 {-khtml-user-drag: element;}

■ドラッグ&ドロップのサンプル ソース全文

以下のサンプルはFirefox・Google Chrome・Safariで動作します。

HTML + JavaScriptソース

<!DOCTYPE html> 
<html lang="ja"> 
<head> 
<meta charset=utf-8>
<title>ドラッグ&ドロップ サンプル</title>
<style>
#fruits {
  /*単なるスタイリング*/
  width:500px; height:100px; margin:20px; background-color:#FF9966; border:1px solid #cc3333;
}
#dropbox {
  /*単なるスタイリング*/
  width:500px; height:100px; margin:20px; background-color:#CCFF66; border:1px solid #00cc00;
  /*以下はwebkit系ブラウザでドラッグ&ドロップを動かすための指定(ブラウザのサポートが進めば、必要なくなると思われます)*/
  -khtml-user-drag: element;
}
</style>
<script>
/***** ドラッグ開始時の処理 *****/
function f_dragstart(event){
  //ドラッグするデータのid名をDataTransferオブジェクトにセット
  event.dataTransfer.setData("text", event.target.id);
}

/***** ドラッグ要素がドロップ要素に重なっている間の処理 *****/
function f_dragover(event){
  //dragoverイベントをキャンセルして、ドロップ先の要素がドロップを受け付けるようにする
  event.preventDefault();
}

/***** ドロップ時の処理 *****/
function f_drop(event){
  //ドラッグされたデータのid名をDataTransferオブジェクトから取得
  var id_name = event.dataTransfer.getData("text");
  //id名からドラッグされた要素を取得
  var drag_elm =document.getElementById(id_name);
  //ドロップ先にドラッグされた要素を追加
  event.currentTarget.appendChild(drag_elm);
  //エラー回避のため、ドロップ処理の最後にdropイベントをキャンセルしておく
  event.preventDefault();
}
</script>
</head>
<body>

<p>好きな果物は何ですか?</p>
<div id="fruits" ondragover="f_dragover(event)" ondrop="f_drop(event)">
<img src="images/apple.gif" id="apple" alt="りんご" draggable="true" ondragstart="f_dragstart(event)">
<img src="images/orange.gif" id="orange" alt="みかん" draggable="true" ondragstart="f_dragstart(event)">
<img src="images/grape.gif" id="grape" alt="ぶどう" draggable="true" ondragstart="f_dragstart(event)">
</div>

<p>下のボックスに入れてください。</p>
<div id="dropbox" ondragover="f_dragover(event)" ondrop="f_drop(event)">
</div>

</body>
</html>
サンプルを別画面で開く

■ドラッグ&ドロップのメソッド・属性

HTML5のドラッグ&ドロップには、以下のメソッド・属性が用意されています。


 The DataTransfer interface

dataTransfer . dropEffect [ = value ] …… 現在の操作の種類を返す("none", "copy", "link", "move")
dataTransfer . effectAllowed [ = value ] …… 許可される操作の種類を返す("none", "copy", "copyLink", "copyMove", "link", "linkMove", "move", "all", "uninitialized")
dataTransfer . items …… ドラッグデータのDataTransferItemsオブジェクトを返す
dataTransfer . setDragImage(element, x, y) …… ドラッグフィードバックを更新する要素を指定する
dataTransfer . addElement(element) …… ドラッグフィードバックを描画する要素を追加する
dataTransfer . types …… データのタイプを返す
data = dataTransfer . getData(format) …… データを取得する
dataTransfer . setData(format, data) …… データをセットする
dataTransfer . clearData( [ format ] ) …… データをクリアする
dataTransfer . files …… ドラッグされているファイルがあればファイルリストを返す

 The DataTransferItems interface

items . length …… ドラッグデータストア内のアイテム数を返す
items[index] …… ドラッグデータストア内のindex番目にエントリされたDataTransferItemオブジェクトを返す
delete items[index] …… ドラッグデータストア内のindex番目のエントリを削除する
items . clear() …… ドラッグデータストア内のすべてのエントリを削除する
items . add(data) …… ドラッグデータストアに新しいエントリを追加する
items . add(data, type) …… ドラッグデータストアに新しいエントリをデータ型を指定して追加する

 The DataTransferItem interface

item . kind …… ドラッグデータ・アイテムの種類を返す("string", "file")
item . type …… ドラッグデータ・アイテムの型を返す
item . getAsString(callback) …… コールバックを呼び出して文字列データを取得する
file = item . getAsFile() …… Fileオブジェクトを取得する

 The DragEvent interface

event . dataTransfer …… DataTransferオブジェクトを返す

 The draggable attribute

element . draggable [ = value ] …… draggable属性の値を返す

 Editing APIs

document . execCommand(commandId [, showUI [, value ] ] ) …… コマンドを実行する
document . queryCommandEnabled(commandId) …… コマンドが有効かどうかを確認する
document . queryCommandIndeterm(commandId) …… コマンドが不確定かどうかを確認する
document . queryCommandState(commandId) …… コマンドの状態を確認する
document . queryCommandSupported(commandId) …… コマンドがサポートされているかどうかを確認する
document . queryCommandValue(commandId) …… コマンドの値を確認する
<前へ 記事一覧へ 次へ>
広告
Sponsors
広告
MuuMuu Domain!
ドメイン取るならお名前.com
現役エンジニアのオンライン家庭教師【CodeCamp】
サイトに広告を掲載してお小遣いが稼げる!【A8.net】
Node.jsコース
はじめてのプログラミングコース
▲ページ先頭へ
HTMLクイックリファレンスについて
© HTMQ