one's way blog

ワクワクを生み出せるWebエンジニアを目指して。

【20:パズル】HTML5のドラッグ&ドロップAPIを使ったパズル

f:id:seintoseiya:20150717002028p:plain
プロジェクトNo.20:パズル

HTML5から利用可能になったドラッグ&ドロップ専用の新しいイベントや新しいメソッド・属性などを使ってみた。
mousedownやmouseupで無理やりできるものもあるが、Googleドライブの様にローカル環境のデータをドラッグでアップロードするとかはこれを使ってできるのだと思う。

draggable属性

ドラッグできる対象のオブジェクトにはdraggable属性をtrueにする必要がある。
href属性が指定されたa要素、および、src属性が指定されたimg要素は、デフォルトでドラッグ可となっているらしいが、
一応、意味合い的に今回は付加しておいた。

HTML
<div id="pieces" ondragover="f_dragover(event)" ondrop="f_dropBase(event)">
	<img src="./img/piece5.png" id="piece5" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece3.png" id="piece3" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece9.png" id="piece9" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece2.png" id="piece2" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece8.png" id="piece8" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece4.png" id="piece4" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece1.png" id="piece1" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece7.png" id="piece7" draggable="true" ondragstart="f_dragstart(event)">
	<img src="./img/piece6.png" id="piece6" draggable="true" ondragstart="f_dragstart(event)">	
</div>

ドラッグ&ドロップのイベント

今回使ったイベントは以下の通り。

dragstart

ドラッグ開始時に発生

dragover

ドラッグ要素がドロップ要素に重なっている間、発生

drop

ドロップ時に発生

処理の流れ

  • ドラッグ開始時にドラッグした対象のオブジェクトをDataTransferオブジェクトにセット
  • ドラップ先でDataTransferオブジェクトの中身を取得して、要素を追加
  • なお、ドラッグ要素がドロップ要素に重なっている間はdragoverイベントをキャンセルして、ドロップ先の要素がドロップを受け付けるようにする必要が有るらしい
JavaScript
/***** ドラッグ開始時の処理 *****/
function f_dragstart(event){
    //ドラッグするデータのid名をDataTransferオブジェクトにセット
    event.dataTransfer.setData("text", event.target.id);
}

/***** ドラッグ要素がドロップ要素に重なっている間の処理 *****/
function f_dragover(event){
    //dragoverイベントをキャンセルして、ドロップ先の要素がドロップを受け付けるようにする
    event.preventDefault();
}
/***** ドロップ時の処理 *****/
function f_dropBase(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();
}
/***** ドロップ時の処理 *****/
function f_drop(event){
    if(event.currentTarget.hasChildNodes()){
        return;
    }
    //ドラッグされたデータの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();
}

全ソースはこちら

github.com