★HTML5のAPI、および、関連仕様
| ドラッグ&ドロップとは
|
ドラッグ&ドロップとは、ウェブページ内の要素やローカル環境に保存されたファイルなどのデータを、 マウスで引きずるように移動させて他の場所に置く操作のことです。 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で制御してやることで、ドラッグ&ドロップ機能を実現します。
|
| ドラッグ操作の概要
|
ドラッグ操作では、ドラッグするデータを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のドラッグ&ドロップには、以下のメソッド・属性が用意されています。
anchor: datatransfer
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 …… ドラッグされているファイルがあればファイルリストを返す anchor: datatransferItems
tems . length …… ドラッグデータストア内のアイテム数を返す
items[index] …… ドラッグデータストア内のindex番目にエントリされたDataTransferItemオブジェクトを返す delete items[index] …… ドラッグデータストア内のindex番目のエントリを削除する items . clear() …… ドラッグデータストア内のすべてのエントリを削除する items . add(data) …… ドラッグデータストアに新しいエントリを追加する items . add(data, type) …… ドラッグデータストアに新しいエントリをデータ型を指定して追加する anchor: datatransferIteminter
item . kind …… ドラッグデータ・アイテムの種類を返す("string", "file")
item . type …… ドラッグデータ・アイテムの型を返す item . getAsString(callback) …… コールバックを呼び出して文字列データを取得する file = item . getAsFile() …… Fileオブジェクトを取得する anchor: dragevent
event . dataTransfer …… DataTransferオブジェクトを返す
anchor: draggable
The draggable attributeelement . draggable [ = value ] …… draggable属性の値を返す
anchor: Editing
Editing APIsdocument . execCommand(commandId [, showUI [, value ] ] ) …… コマンドを実行する
document . queryCommandEnabled(commandId) …… コマンドが有効かどうかを確認する document . queryCommandIndeterm(commandId) …… コマンドが不確定かどうかを確認する document . queryCommandState(commandId) …… コマンドの状態を確認する document . queryCommandSupported(commandId) …… コマンドがサポートされているかどうかを確認する document . queryCommandValue(commandId) …… コマンドの値を確認する |