ドラッグ&ドロップでページ内の要素を移動させる (任意の位置への配置ではない階層移動) - JavaScript

HTML JavaScriptのページでドラッグ&ドロップでページ内の要素を移動させるコードを紹介します。

概要

HTMLページで要素をドラッグ&ドロップで移動させるコードを紹介します。要素の絶対座標を指定する方法ではなく、 ドロップした要素の子要素としてドロップオブジェクトを配置する方法を紹介します。

ドラッグ&ドロップは、DragStart,DragOver,Dropイベントを利用します。HTML要素のドラッグの詳細についてはこちらの記事も参照して下さい。
ドロップ確定時の移動にはDOMを操作するメソッドである appendChild メソッドを利用します。

プログラム

コード

下記のHTMLを作成します。
DragDropMove.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title></title>
  <link rel="stylesheet" href="DragDropMove.css" />

  <script type="text/javascript">
    function onDragStart(e) {
      e.dataTransfer.effectAllowed = 'move';
      e.dataTransfer.setData('text', e.target.id);
    }

    function onDragOver(e) {
      e.preventDefault();
      e.dataTransfer.dropEffect = 'move';
    }

    function onDrop(e) {
      if (e.stopPropagation) e.stopPropagation();
      var eid = e.dataTransfer.getData('text');
      var elem = document.getElementById(eid);
      e.target.appendChild(elem);
    }
  </script>

</head>
<body>
  <img id="DragItem1" ondragstart="onDragStart(event);" src="image1.png" />
  <img id="DragItem2" ondragstart="onDragStart(event);" src="image2.png" />

  <div></div>

  <div id="DropArea" ondrop="onDrop(event);" ondragover="onDragOver(event);">
    ドロップエリアです。
  </div>
</body>
</html>
DragDropMove.css
#DropArea {
  width:600px;
  height:320px;
  border:solid 1px #ff6a00;
}

画像

以下の画像を用意しています。
image1.png
image1.png

image2.png
image2.png

解説

ドラッグが可能な要素が以下です。imgタグはドラッグ可能な要素のためdraggableプロパティの記述は不要です。デフォルトでドラッグが不可能な要素(divタグなど)では draggable="true" を記述する必要があります。
また、ドラッグを開始した際に処理をするイベントを ondragstart 属性で指定します。
  <img id="DragItem1" ondragstart="onDragStart(event);" src="image1.png" />
  <img id="DragItem2" ondragstart="onDragStart(event);" src="image2.png" />

ドラッグ要素をドロップできるエリアの記述が以下です。ドロップ可能なエリアには ondrop 属性でドロップイベント、 ondragover でドラッグ要素がドロップエリアに入った場合の処理をするイベントを記述します。
  <div id="DropArea" ondrop="onDrop(event);" ondragover="onDragOver(event);">
    ドロップエリアです。
  </div>

DragStartイベントが以下です。引数のイベントのdataTransferオブジェクトにドラッグ時の効果やドラッグ情報を設定します。effectAllowedプロパティにドラッグ時の効果を設定します。今回は要素を移動する動作のため move を設定します。また、ドラッグにより渡される情報を setData メソッドで設定します。今回はドラッグされた要素のidの値を設定します。
    function onDragStart(e) {
      e.dataTransfer.effectAllowed = 'move';
      e.dataTransfer.setData('text', e.target.id);
    }

ドラッグ要素がドロップエリアに入った場合のイベントが以下です。引数のイベントの prevnetDefault() メソッドを呼び出しデフォルトの動作をキャンセルします。また、effectAllowedプロパティにドラッグ時の効果を設定します。今回は要素を移動する動作のため move を設定します。
    function onDragOver(e) {
      e.preventDefault();
      e.dataTransfer.dropEffect = 'move';
    }

ドラッグ要素をドロップエリアにドロップしたときのイベントです。引数のイベントの stopPropagation() メソッドを呼び出しイベントの伝搬を抑止します。
ドロップされた要素の情報はイベントオブジェクトのdataTransfer.getData() メソッドで取得します。ドラッグ開始時に text形式でドラッグ要素のidを設定しているため、戻り値には ドロップされた要素のidが取得できます。
getElementById() メソッドを呼び出し、取得できた要素のIDから要素のオブジェクトを取得します。イベントオブジェクトの target プロパティがドロップエリアの要素のオブジェクトになります。 appendChild メソッドを呼び出し、ドロップエリアにドロップされた要素を追加します。
    function onDrop(e) {
      if (e.stopPropagation) e.stopPropagation();
      var eid = e.dataTransfer.getData('text');
      var elem = document.getElementById(eid);
      e.target.appendChild(elem);
    }

実行結果

上記のHTMLファイルをWebブラウザで表示します。下図の画面が表示されます。


画像をドラッグすると、半透明表示になりドラッグ可能状態になります。


画像をドラッグしてドロップエリア内に移動し、ドロップします。


画像をドロップすると、画像がドロップエリア内に移動します。


もう一つの画像もドラッグしてドロップエリア内でドロップします。


もう一つの画像もドロップエリアに移動しました。ドロップされた要素はドロップエリアのコンテンツの一番最後に追加されることも確認できます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2020-10-18
作成日: 2020-04-06
iPentec all rights reserverd.