序章

ドラッグアンドドロップは、多くのグラフィカルユーザーインターフェイスで見られる一般的なユーザー操作です。

ドラッグアンドドロップ機能をアプリに追加するための既存のJavaScriptライブラリがあります。 ただし、ライブラリが利用できない場合や、プロジェクトに必要のないオーバーヘッドや依存関係が生じる場合があります。 このような状況では、最新のWebブラウザーで使用できるAPIの知識により、代替ソリューションを提供できます。

HTMLドラッグアンドドロップAPIは、DOMのイベントモデルに依存して、ドラッグまたはドロップされているものに関する情報を取得し、ドラッグアンドドロップでその要素を更新します。 JavaScriptイベントハンドラーを使用すると、任意の要素をドラッグ可能なアイテムまたはドロップできるアイテムに変えることができます。

このチュートリアルでは、HTMLドラッグアンドドロップAPIとバニラJavaScriptを使用して、イベントハンドラーを使用するドラッグアンドドロップの例を作成します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

  • ドラッグアンドドロップAPI(Chrome 4以降、Firefox 3.5以降、Safari 3.1以降、Edge 18以降)をサポートする最新のWebブラウザー。

ステップ1—プロジェクトと初期マークアップの作成

私たちのプロジェクトは、2種類の子要素を持つコンテナで構成されます。

  • ドラッグできる子要素
  • 要素をドロップできる子要素

まず、ターミナルウィンドウを開き、新しいプロジェクトディレクトリを作成します。

  1. mkdir drag-and-drop-example

次に、そのディレクトリに移動します。

  1. cd drag-and-drop-example

次に、を作成します index.html そのディレクトリ内のファイル:

  1. nano index.html

次に、HTMLWebページのボイラープレートコードを追加します。

index.html
<!DOCTYPE html>
<html>
  <head>
    <title>My Drag-and-Drop Example</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
  </body>
</html>

そして、 <body> タグはあなたを追加します draggable アイテムとあなたの dropzone (ドロップターゲット):

index.html
<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
  >
    dropzone
  </div>
</div>

ファイルを保存して閉じます。 次に、を作成します style.css ファイル:

  1. nano style.css

次に、要素のスタイルを追加します index.html ファイル:

style.css
.example-parent {
  border: 2px solid #DFA612;
  color: black;
  display: flex;
  font-family: sans-serif;
  font-weight: bold;
}

.example-origin {
  flex-basis: 100%;
  flex-grow: 1;
  padding: 10px;
}

.example-draggable {
  background-color: #4AAE9B;
  font-weight: normal;
  margin-bottom: 10px;
  margin-top: 10px;
  padding: 10px;
}

.example-dropzone {
  background-color: #6DB65B;
  flex-basis: 100%;
  flex-grow: 1;
  padding: 10px;
}

これにより、アプリにフォーマットが追加されます。 今、あなたは見ることができます index.html ブラウザで、これにより draggable <div>dropzone <div>.

次に、明示的に最初のものを作成します <div> 追加することでドラッグ可能 draggable 属性:

index.html
<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
  >
    dropzone
  </div>
</div>

ファイルを保存して閉じます。

最後に、表示 index.html 再びブラウザで。 クリックすると draggable <div> 画面上でドラッグすると、移動していることが視覚的に示されます。

のデフォルト値 draggable 属性は auto. つまり、要素がドラッグ可能かどうかは、ブラウザのデフォルトの動作によって決まります。 通常、これは、テキストの選択、画像、およびリンクを指定せずにドラッグできることを意味します draggable="true".

これで、ドラッグ可能な要素を含むHTMLファイルができました。 追加に移ります onevent ハンドラー。

ステップ2—JavaScriptを使用したドラッグアンドドロップイベントの処理

現在、ドラッグ可能な要素をドラッグしているときにマウスを離しても、何も起こりません。 DOM要素のドラッグアンドドロップでアクションをトリガーするには、ドラッグアンドドロップAPIを利用する必要があります。

  • ondragstart:このイベントハンドラーは draggable 要素と火が dragstart イベントが発生します。
  • ondragover:このイベントハンドラーは dropzone 要素と火が dragover イベントが発生します。
  • ondrop:このイベントハンドラーは、 dropzone 要素と火が drop イベントが発生します。

注:合計8つのイベントハンドラーがあります。 ondrag, ondragend, ondragenter, ondragexit, ondragleave, ondragover, ondragstart、 と ondrop. この例では、それらすべてを必要としません。

まず、新しいものを参照しましょう script.js 私たちのファイル index.html:

index.html
<body>
  ...
  <script src="script.js"></script>
</body>

次に、新しいを作成します script.js ファイル:

  1. nano script.js

The DataTransfer オブジェクトは、発生している現在のドラッグに関連する情報を追跡します。 ドラッグとドロップで要素を更新するには、直接アクセスする必要があります DataTransfer 物体。 これを行うには、 dataTransfer DOM要素のプロパティ DragEvent.

注: DataTransfer オブジェクトは、同時にドラッグされている複数の要素の情報を技術的に追跡できます。 この例では、1つの要素のドラッグに焦点を当てます。

The dataTransfer オブジェクトの setData メソッドを使用して、現在ドラッグされている要素のドラッグ状態情報を設定できます。 2つのパラメータが必要です。

  • 2番目のパラメーターの形式を宣言する文字列
  • 転送される実際のデータ

私たちの目標は私たちを動かすことです draggable 要素を新しい親要素に。 私たちは私たちを選択できる必要があります draggable ユニークな要素 id. 設定できます id ドラッグされた要素の setData 後で使用できるようにする方法。

私たちの再訪しましょう script.js ファイルを作成し、使用する新しい関数を作成します setData:

script.js
function onDragStart(event) {
  event
    .dataTransfer
    .setData('text/plain', event.target.id);
}

注: Internet Explorer 9〜11には、使用に問題があると報告されています 'text/plain'. フォーマットはする必要があります 'text' そのブラウザ用。

ドラッグされたアイテムのCSSスタイルを更新するには、DOMイベントを再度使用し、必要なスタイルを設定することで、そのスタイルにアクセスできます。 currentTarget.

関数に追加して、 backgroundColoryellow:

script.js
function onDragStart(event) {
  event
    .dataTransfer
    .setData('text/plain', event.target.id);

  event
    .currentTarget
    .style
    .backgroundColor = 'yellow';
}

注:ドラッグのみのスタイルが必要な場合は、変更したスタイルをドロップ時に手動で再度更新する必要があります。 ドラッグの開始時に何かを変更した場合、ドラッグした要素は、元に戻さない限り、その新しいスタイルを維持します。

これで、ドラッグを開始するときのJavaScript関数ができました。

追加できます ondragstartdraggable の要素 index.html:

index.html
<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      draggable
    </div>
  </div>

  <div class="example-dropzone">
    dropzone
  </div>
</div>

意見 index.html ブラウザで。 ここでアイテムをドラッグしようとすると、関数で宣言されたスタイルが適用されます。

ただし、クリックを離しても何も起こりません。

このシーケンスで起動される次のイベントハンドラーは ondragover.

次のような特定のDOM要素のデフォルトのドロップ動作 <div>■ブラウザの場合、通常、ドロップは受け入れられません。 この動作は、実装しようとしている動作をインターセプトします。 目的のドロップ動作を確実に得るために、 preventDefault.

もう一度見てみましょう script.js ファイルを作成し、使用する新しい関数を作成します preventDefault. 次のコードをファイルの最後に追加します。

script.js
function onDragOver(event) {
  event.preventDefault();
}

今、私たちは追加することができます ondragover 私たちに dropzone の要素 index.html:

index.html
<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
    ondragover="onDragOver(event);"
  >
    dropzone
  </div>
</div>

この時点では、実際のドロップを処理するコードはまだ作成されていません。 このシーケンスで発生する最後のイベントハンドラーは ondrop.

私たちの再訪しましょう script.js ファイルを作成し、新しい関数を作成します。

以前に保存したデータを参照できます dataTransfer オブジェクトの setData 方法。 我々は使用するだろう dataTransfer オブジェクトの getData 方法。 私たちが設定したデータは id、それが私たちに返されるものです:

script.js
function onDrop(event) {
  const id = event
    .dataTransfer
    .getData('text');
}

私たちを選択してください draggable 要素と id 取得しました:

script.js
function onDrop(event) {
  // ...

  const draggableElement = document.getElementById(id);
}

私たちを選択してください dropzone エレメント:

script.js
function onDrop(event) {
  // ...

  const dropzone = event.target;
}

私たちを追加します draggable 要素に dropzone:

script.js
function onDrop(event) {
  // ...

  dropzone.appendChild(draggableElement);
}

リセットする dataTransfer 物体:

script.js
function onDrop(event) {
  // ...

  event
    .dataTransfer
    .clearData();
}

今、私たちは追加することができます ondrop 私たちに dropzone の要素 index.html:

index.html
<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
    ondragover="onDragOver(event);"
    ondrop="onDrop(event);"
  >
    dropzone
  </div>
</div>

これが完了すると、ドラッグアンドドロップ機能が完成します。 意見 index.html ブラウザでドラッグします draggable 要素に dropzone.

この例では、単一のドラッグ可能なアイテムと単一のドロップターゲットのシナリオを処理します。 複数のドラッグ可能なアイテム、複数のドロップターゲットを設定し、他のすべてのドラッグアンドドロップAPIイベントハンドラーを使用してカスタマイズできます。

ステップ3—複数のドラッグ可能なアイテムを使用して高度な例を作成する

このAPIを使用する方法のもう1つの例を次に示します。ドラッグ可能なタスクを含むToDoリストから移動できます。 "To-do" 列から "Done" 桁。

独自のやることリストを作成するには、独自のドラッグ可能な要素をさらに追加します idsから index.html:

index.html
<div class="example-parent">
  <h1>To-do list</h1>
  <div class="example-origin">
    To-do
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 1
    </div>
    <div
      id="draggable-2"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 2
    </div>
    <div
      id="draggable-3"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 3
    </div>
    <div
      id="draggable-4"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 4
    </div>
  </div>

  <div
    class="example-dropzone"
    ondragover="onDragOver(event);"
    ondrop="onDrop(event);"
  >
    Done
  </div>
</div>

意見 index.html ブラウザで、To-do列の項目をDone列にドラッグします。 To Doアプリケーションを作成し、機能をテストしました。

結論

この記事では、最新のWebブラウザーで使用できるドラッグアンドドロップ機能を調べるためのToDoアプリを作成しました。

ドラッグアンドドロップAPIは、ドラッグアンドドロップ以外のアクションをカスタマイズするための複数のオプションを提供します。 たとえば、ドラッグしたアイテムのCSSスタイルを更新できます。 また、アイテムを移動する代わりに、ドラッグ可能なアイテムをコピーして、ドロップ時に複製されるようにすることもできます。

多くのWebブラウザーはこのテクノロジーをサポートしていますが、オーディエンスがこの機能をサポートしないデバイスで構成されている場合は、このテクノロジーに依存できない可能性があることに注意してください。

ドラッグアンドドロップAPIを使用してドロップできるすべての詳細については、MDNのドキュメントを確認してください。