以前、vbsめーかーのページ作った時は手探りでいろいろ調べてjQueryUIのsortableっていうのを使って並べ替えする為のUIを組んでいました。
勉強し直してたら、HTML5のAPI関連仕様の中にドラッグ&ドロップでDOM制御できる感じの機能が用意されていることを知ったので試しに自分でも書いてみる。
今日もこちらのサイトをベースに勉強してます。
1.仕組みの整理
- ドラッグする要素にdraggable属性を設定
- ドロップ先にdropzone属性を設定
・・・と思ったら、dropzone属性はまだブラウザ対応してないらしい。
2.HTML5のドラッグ&ドロップEventを使ってJavascript制御する
DataTransferオブジェクトっていうのを使って管理していくみたいだ。
ん?でも、FireFox・Chrome・Safariに対応って書いてあるな・・・。
とりあえず、試してみましょ。
まず、枠を作る。
<div class="droparea" ondrop="icon_drop(event)" ondragover="icon_dragover(event)"> <img id='draggable_icon1' class="alignnone wp-image-189" src="https://yizm.work/wp-content/uploads/2018/11/wan2.png" alt="" width="60" height="60" draggable="true" ondragstart="icon_dragstart(event)"/> <img id='draggable_icon2' class="alignnone wp-image-189" src="https://yizm.work/wp-content/uploads/2018/11/wan3.png" alt="" width="70" height="70" draggable="true" ondragstart="icon_dragstart(event)"/> </div>
画像の方に「draggable="true"」付けて、「ondragstart="icon_dragstart(event)"」でイベント発生元の要素をキャッチするよと。
div枠の方に「ondrop="icon_drop(event)"」と「ondragover="icon_dragover(event)"」を設定してみた。
それぞののイベントはこんな感じ。
function icon_dragstart(event){
event.dataTransfer.effectAllowed = "move";
event.dataTransfer.setData("text", event.target.id);
}
function icon_dragover(event){
event.preventDefault() ;
event.dataTransfer.dropEffect = "move";
}
function icon_drop(e){
var mouseX , mouseY;
if (e) {
mouseX = e.pageX;
mouseY = e.pageY;
} else {
mouseX = event.pageX + document.body.scrollLeft;
mouseY = event.pageY + document.body.scrollTop;
}
var id_name = e.dataTransfer.getData("text");
var drag_elm =document.getElementById(id_name);
mouseX = mouseX - (parseInt(drag_elm.width) / 2);
mouseY = mouseY - (parseInt(drag_elm.height) / 2);
drag_elm.style.position = 'absolute';
drag_elm.style.left = mouseX + 'px';
drag_elm.style.top = mouseY + 'px';
}
↓アイコンを色枠の中でドラッグ&ドロップしてみてちょ。
ondragのイベントは、onmousemoveみたいにドラッグ操作でマウスポインタが移動するたびに連続的に発生するみたいだ。
移動中にもアイコン動かしてみようと思ってonmousemoveイベント拾おうとしてみたけど、ドラッグ中はondragイベントしか発生してなかった。
ondropイベントの引数eventからXY位置を取得してアイコン位置を自由に移動できる様にしてみた。
ondragoverイベントで特定要素の枠内に移動したの拾えるからグリッドでマスの領域拾えば将棋みたいな盤目遊びできるかな?