2
3

More than 1 year has passed since last update.

JavaScript で ドラッグ&ドロップをやってみる

Last updated at Posted at 2023-06-09

JavaScript でドラッグ&ドロップを簡単につくってみる
出来上がったやつのサンプルページのリンク、イメージはこんな感じ

See the Pen Untitled by sueasen (@sueasen) on CodePen.

ドラッグ&ドロップ概要

やることとしては以下をする感じ

  • ドラッグする対象の draggabletrue にする
  • ドラッグする対象に dragstart のイベントを追加する
  • ドロップする対象に drop, dragenter, dragleave, dragover のイベントを追加する
  • event.dataTransfersetData, 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;
}

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3