【JavaScript】ドラッグ・アンド・ドロップのクラスの作成方法

JavaScript

JavaScriptのクラスを使って、ドラッグ・アンド・ドロップの実装方法を紹介します。

ドラッグ・アンド・ドロップのデモ

See the Pen
JavaScript – ドラッグ・アンド・ドロップ
by Sosak (@Sosak2021)
on CodePen.

デモでうまく動作しないことがありますが、Edit on codepenを押してもらってcodepen上でみてもらうとちゃんと動作します。

JavaScriptコードの解説


  document.addEventListener("DOMContentLoaded", () => {
    const main = new Main();
  });
  
  class Main {
    constructor() {
      this.fill = document.querySelector(".fill");
      this.empties = document.querySelectorAll(".empty");
      this._init();
    }
    _init() {
      this._dragInit();
    }
    _dragInit() {
      //   thisはクラス自体にしたいのでアロー関数
      this.fill.addEventListener("dragstart", () => {
        this.dragStart();
      });
      //   thisはクラス自体にしたいのでアロー関数
      this.fill.addEventListener("dragend", () => {
        this.dragEnd();
      });
      for (const empty of this.empties) {
        empty.addEventListener("dragover", this.dragOver);
        empty.addEventListener("dragenter", this.dragEnter);
        empty.addEventListener("dragleave", this.dragLeave);
        //   thisはクラス自体にしたいのでアロー関数
        empty.addEventListener("drop", () => {
          this.dragDrop(empty);
        });
      }
    }
    dragStart() {
      //   クラス名を付与
      this.fill.className += " hold";
      // 元の場所にある画像を非表示
      setTimeout(() => (this.fill.className = "invisible"), 0);
    }
    dragEnd() {
      //   画像を表示
      this.fill.className = "fill";
    }
    dragOver(e) {
      //   ドラップを使うにはpreventDefault必須
      e.preventDefault();
    }
    dragEnter(e) {
      //   ドラップを使うにはpreventDefault必須
      e.preventDefault();
      this.className += " hovered";
    }
    dragLeave() {
      this.className = "empty";
    }
    dragDrop(empty) {
      empty.className = "empty";
      empty.append(this.fill);
    }
  }
  
  

まず、ドラッグ・アンド・ドロップで動かしたい要素には、draggable="true"という属性を付与してあげる必要があります。
また、ブラウザのデフォルトの挙動が邪魔をする可能性があるので、dragOverは必ずpreventDefault()を設定します。
あとは、thisの値が合うように、bindやアロー関数などを使って、望んでいるthisを得られるように作成していきます。

ドラッグのイベント

ドラッグのイベントは以下の通りです。

  • dragstart: ドラッグ開始時
  • drag: ドラッグ中
  • dragend: ドラッグ終了時

イベントをリスナーに登録するとき、大文字になっていたりするとイベントがセットされないので、注意しましょう。

ドロップのイベント

  • dragenter: マウスポインタがドロップ要素の内側に入った時
  • dragover: マウスポインタがドロップ要素の内側にある時
  • dragleave: マウスポインタがドロップ要素の内側から出た時
  • drop: 要素にドロップした時

dragoverとdropはブラウザのデフォルトの挙動を止める必要があります。
そのため、忘れずにpreventDefault()をセットします。