JavaScript でドラッグ&ドロップを簡単につくってみる
出来上がったやつのサンプルページのリンク、イメージはこんな感じ
See the Pen Untitled by sueasen (@sueasen) on CodePen.
ドラッグ&ドロップ概要
やることとしては以下をする感じ
- ドラッグする対象の
draggable
をtrue
にする - ドラッグする対象に
dragstart
のイベントを追加する - ドロップする対象に
drop
,dragenter
,dragleave
,dragover
のイベントを追加する -
event.dataTransfer
のsetData
,getData
でドラッグする情報の受け渡しをする
ドラッグ&ドロップのイベント概要
サンプルで使ってるやつだけ...
ドラッグするタグに設定するイベント
dragstart
ドラッグ開始時イベント
event.dataTransfer.setData("text", event.currentTargetより取得する値)
でドラッグする情報が設定できる
event.dataTransfer.setDate
の第一引数にデータ形式(型)を設定, オブジェクト(HTMLElement) とかは設定できなそう...
ドロップするタグに設定するイベント
drop
: ドロップ時イベント
event.dataTransfer.getData("text")
でドラッグ時に設定した値を取得
ドラッグ開始時に設定したときの第一引数のデータ形式と同じ値を引数にする
dragenter
: ドラッグしながらドロップ対象に入ってきた時のイベント
event.currentTerget
でドロップ対象がとれる
dragleave
: ドラッグしながらドロップ対象を出た時のイベント
event.currentTerget
でドロップ対象がとれる
dragover
: ドラッグしながらドロップ対象の上にいる時のイベント
event.preventDefault()
でイベントをキャンセルする
キャンセルしないと定期的にイベント発生して drop
が発火しない(しずらいだけかも...)
サンプルコード
HTML
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h3>ドラッグ&ドロップ</h3>
<div class="flex-row">
<div id="1" class="box drag">どらっぐ1</div>
<div id="2" class="box drop">どろっぷ1</div>
<div id="3" class="box drop">どろっぷ2</div>
<div id="4" class="box drop">どろっぷ3</div>
</div>
</div>
</body>
<script src="script.js"></script>
</html>
JavaScript
// drag 設定
document.querySelector(".box.drag").draggable = true;
document.querySelector(".box.drag").addEventListener("dragstart", onDragStart);
// drop 設定
document.querySelectorAll(".box.drop").forEach((element) => {
element.addEventListener("drop", onDrop);
element.addEventListener("dragover", onDragover);
element.addEventListener("dragenter", onDragenter);
element.addEventListener("dragleave", onDragleave);
});
/**
* ドラッグ処理
* @param {Event} event
*/
function onDragStart(event) {
event.dataTransfer.setData("text", event.currentTarget.id);
}
/**
* ドロップ処理
* @param {Event} event
*/
function onDrop(event) {
event.currentTarget.classList.remove("dragging");
const boxs = [...document.querySelectorAll(".box")];
if (boxs.indexOf(event.currentTarget) === 0) {
event.currentTarget.before(document.getElementById(event.dataTransfer.getData("text")));
} else {
event.currentTarget.after(document.getElementById(event.dataTransfer.getData("text")));
}
}
/**
* 操作が要素上に入ってきたとき
* @param {Event} event
*/
function onDragenter(event) {
event.currentTarget.classList.toggle("dragging");
}
/**
* 操作が要素上から出たとき
* @param {Event} event
*/
function onDragleave(event) {
event.currentTarget.classList.toggle("dragging");
}
/**
* 操作が要素上を通過してるとき
* @param {Event} event
*/
function onDragover(event) {
event.preventDefault();
}
CSS
@charset "utf-8";
body {
text-align: center;
}
.flex-row {
display: flex;
justify-content: center;
}
.box {
line-height: 80px;
height: 80px;
width: 80px;
border: 1px solid gray;
}
.box.drag {
background-color: skyblue;
}
.box.dragging {
background-color: skyblue;
opacity: 0.5;
}