0Pricing
HTML Academy · レッスン

dragoverとdropイベント

有効なドロップ先を定義し、dropイベントを処理します

「dragoverとdropイベント」はCoddyKit上の無料HTML Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはHTML Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 HTML Academyコースには全4レッスンが含まれています。

ドロップ先には2つのハンドラーが必要

ドロップ先では、dragover(ドロップを許可するため)とdrop(データを受け取るため)の両方を処理する必要があります。dragoverがなければ、デフォルト動作が「どの要素もドロップ先ではない」であるため、ブラウザはdropの発生を拒否します。

preventDefaultは必須

dragoverハンドラーではe.preventDefault()を呼び出す必要があります。これにより、ドロップを拒否するブラウザのデフォルト動作をキャンセルします。これを行わないと、カーソルは「禁止」のままになり、ユーザーが何をしてもdropイベントは発生しません。

zone.addEventListener("dragover", (e) => {
  e.preventDefault();
});
zone.addEventListener("drop", (e) => {
  e.preventDefault();
  console.log(e.dataTransfer.getData("text/plain"));
});

dragenterとdragleave

dragenterはカーソルがターゲットに入ったときに1回発生し、dragleaveはカーソルがターゲットから離れたときに1回発生します。これらを使って「ドラッグオーバー」の視覚的なハイライトを切り替えます。入ったときにクラスを追加し、離れたときに削除することで、ユーザーはどの領域がドロップを受け取るかを確認できます。

子要素でもdragleaveが発生する

注意すべき仕様上の癖があります。カーソルを子要素の上に移動すると、親要素でdragleaveが発生した後、子要素でdragenterが発生します。dragenterでインクリメントし、dragleaveでデクリメントするカウンターを使い、カウンターが0に戻ったときだけハイライトを削除してください。

let counter = 0;
zone.addEventListener("dragenter", () => {
  counter++;
  zone.classList.add("over");
});
zone.addEventListener("dragleave", () => {
  counter--;
  if (counter === 0) zone.classList.remove("over");
});

dropEffectの設定

dragover内でe.dataTransfer.dropEffect = "move"(または「copy」、「link」、「none」)を設定すると、カーソルを制御し、何が起きるかをドラッグ元に伝えられます。この効果はドラッグ元のeffectAllowedと互換性がなければならず、互換性がなければドロップは拒否されます。

dropでデータを読み取る

dropハンドラーで、setDataに使用したものと同じMIMEタイプ(通常は「text/plain」)を指定してe.dataTransfer.getData(format)を呼び出します。その後、IDで要素を検索してターゲットに追加したり、データモデルを更新したり、アプリケーションに必要な処理を行ったりします。

dropでもデフォルト動作を防ぐ

dropハンドラーでもe.preventDefault()が必要です。これを行わないと、ブラウザはネイティブの動作に戻ります。ドロップされたURLの場合はリンク先への遷移となり、ページの状態がすぐに失われてしまいます。

デスクトップからのドロップ

ブラウザは、OSからドラッグされたファイルをe.dataTransfer.filesにデータを設定したdropイベントとして処理します。FileListを反復処理し、File APIで各ファイルを読み込むことで、画像のアップロード、ログファイルビューアー、ドキュメントインポーターなどに対応できます。

zone.addEventListener("drop", (e) => {
  e.preventDefault();
  for (const file of e.dataTransfer.files) {
    console.log(file.name, file.size);
  }
});

dataTransferで複数のタイプを扱う

setDataでは、同じペイロードを複数のMIMEタイプで保存できます。「text/plain」はフォールバック用、「text/uri-list」はURL用、「application/json」は構造化されたペイロード用です。ドロップ先は、getDataを通じて理解できる中で最も適したタイプを選択します。

タッチイベントとの連携

モバイルブラウザは、タッチ操作からdragoverやdropを合成しません。統一された操作感を実現するには、Pointer Eventsと手動のヒットテストを使用するか、違いを抽象化するライブラリを利用してください。ネイティブHTML5 DnDはデスクトップ専用と考えるのが適切です。

パフォーマンスのヒント

dragoverはカーソルの移動中、継続的に発生し、1秒間に何十回も呼び出されることがあります。ハンドラーは軽量に保ってください。内部で負荷の高いDOM検索やレイアウトの読み取りを避けます。dragenterで矩形をキャッシュし、カーソルがターゲット上にある間は再利用してください。

理解度チェック

dragoverハンドラーでe.preventDefault()を呼び出すまで、ターゲットでdropイベントが発生しないのはなぜですか?

まとめ

機能するドロップ先は、dragover(必ずpreventDefaultを呼び出し、必要に応じてdropEffectを設定)とdrop(再度preventDefaultを呼び出し、その後dataTransfer.getDataまたはdataTransfer.filesを読み取る)の両方を監視します。ハイライトにはdragenterとdragleaveをカウンターと組み合わせて使用し、dragoverは非常に頻繁に発生するため、ハンドラーを軽量に保ってください。

よくある質問

「dragoverとdropイベント」レッスンは無料ですか?

はい。「dragoverとdropイベント」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、HTML Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 HTML Academyコースには全4レッスンが含まれています。

「dragoverとdropイベント」で何を学びますか?

有効なドロップ先を定義し、dropイベントを処理します ブラウザで直接実行するハンズオンコードでHTML Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

HTML Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのHTML Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「dragoverとdropイベント」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このHTML Academyレッスンでコードを書いて実行できますか?

はい。すべてのHTML Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. draggable属性とdragstartイベント
  2. dragoverとdropイベント
  3. dataTransferオブジェクト
  4. 実践:ドラッグで並べ替えるリスト
← HTML Academyに戻る