1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ドラッグ&ドロップのしくみ|ドラッグ元とドロップ先両方作ってみた

Last updated at Posted at 2025-11-30

いつも何気なく行うファイルのドラッグアンドドロップ。

ドラッグアンドドロップの操作イメージ

どのような仕組みで動いているのか、どんなデータが受け渡しされているのか
サンプルアプリを作成して試してみました。

本記事はwindowsで動作確認を行っています。

ブラウザでファイル受け取り

ファイルのアップロード機能とよく一緒に用意されるドラッグアンドドロップ。シンプルなhtmlファイルをjsファイルを用意して、どのようなデータを受け取っているのか表示できるようにしました。

index.html

単なるdivで枠を用意しました。テキストエリアは、ドロップしたファイルの情報を表示する場所です。

index.html
<div
    id="drop-area"
    style="
        width: 300px;
        height: 200px;
        border: 2px dashed gray;
        text-align: center;
        line-height: 200px;
    "
>
    ここにドラッグ&ドロップ
</div>

<h3>ファイルの内容</h3>
<textarea id="log-area" rows="10" cols="50" readonly></textarea>
<script src="index.js"></script>

index.js

dropイベントでファイルを受け取り、中身を表示します。

index.js
const logArea = document.getElementById("log-area");
function log(message) {
    logArea.value += message + "\n";
}

function logClear() {
    logArea.value = "";
}

const dropArea = document.getElementById("drop-area");

// ファイルをドラッグしてきた
dropArea.addEventListener("dragover", (event) => {
    event.preventDefault();
    dropArea.style.backgroundColor = "lightcyan";
});
// ドラッグしながら出ていった
dropArea.addEventListener("dragleave", () => {
    dropArea.style.backgroundColor = "white";
});

// ファイルドロップ
dropArea.addEventListener("drop", (event) => {
    event.preventDefault();
    // ドロップしたら色を戻す
    dropArea.style.backgroundColor = "white";
    const dataTransfer = event.dataTransfer;
    // 読み取れなかったら終了
    if (!dataTransfer) return;

    // 初期化
    logClear();

    for (const type of dataTransfer.types) {
        log(`タイプ: ${type}`);
    }
    if (dataTransfer.files.length > 0) {
        log("ドロップされたファイル:");
        Array.from(dataTransfer.files).forEach((file) => {
            const reader = new FileReader();
            reader.onload = () => {
                log(`名前: ${file.name}`);
                log(` - MIMEタイプ: ${file.type}`);
                log(` - サイズ: ${file.size} bytes`);
                log(`中身:\n${reader.result}`);
            };
            reader.onerror = () => {
                log("読み込みエラー:", reader.error);
            };

            reader.readAsText(file);
        });
    }
});

dataTransferを利用してドロップされたデータの情報を取得します。

const dataTransfer = event.dataTransfer;

複数ファイルの受け渡しにも対応しているためforEachで取り出しています。

Array.from(dataTransfer.files).forEach((file) => {
    // ファイルごとに処理

それぞれ、ファイル名、MIMEタイプ、ファイルサイズを取得することができます。

log(`名前: ${file.name}`);
log(` - MIMEタイプ: ${file.type}`);
log(` - サイズ: ${file.size} bytes`);

MIMEタイプはファイルの種類をタイプ/サブタイプの形式で表したものです。例えば、png画像の場合image/pngとなります。

ファイルの内容自体を取得するには別途FileReaderを用意して、読み込みます。

const reader = new FileReader();
reader.onload = () => {
    // ファイル読み込み完了したら表示
    log(`中身:\n${reader.result}`);
};
reader.onerror = () => {
    log("読み込みエラー:", reader.error);
};
// テキスト形式で読み込み
reader.readAsText(file);

テキストエリアに内容を表示するために文字列が取得できるreadAsTextを使用しています。

動作確認

index.htmlをブラウザで表示して動作確認します。VScodeのデバッグ実行を利用しました。
windowsのエクスプローラーより、適当なファイルをドラッグアンドドロップします。

ドラッグアンドドロップの操作イメージ

テキストエリアにファイルの内容が表示されます。

タイプ: Files
ドロップされたファイル:
名前: image.png
 - MIMEタイプ: image/png
 - サイズ: 23878 bytes
中身:
�PNG
...(以下略)

中身については、バイナリデータである画像ファイルを無理やり文字列として表示しているため、文字化けしまくっています。

他にもファイルをドロップしてみます。

タイプ: Files
ドロップされたファイル:
名前: index.js
 - MIMEタイプ: text/javascript
 - サイズ: 1598 bytes
中身:
const logArea = document.getElementById("log-area");
function log(message) {
    logArea.value += message + "\n";
}...(以下略)

テキスト形式のファイルは、読める形でファイルの中身が取得できました。

Windows Formアプリでファイル送り出し

ドラッグアンドドロップのドラッグ元、エクスプローラーからファイルをドラッグすることがほとんどです。Windows Formアプリを作成してファイルのドラッグできるようにしてみます。

画面レイアウト

Visual Studioより、.NETのフォームアプリを作成します。

適当にラベルを設置します。

ラベル配置例

ラベルに対し、プロパティよりMouseDownのイベントを作成します。

イベント設定

MainForm.cs

MouseDownのイベントを実装します。

MainForm.cs
namespace FileDragDemo
{

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void Label_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                // ファイルパス
                string[] files = { @"D:\image.png" };

                // FileDrop として設定
                DataObject data = new DataObject(DataFormats.FileDrop, files);

                // ドラッグ開始
                DoDragDrop(data, DragDropEffects.Copy);
            }
        }
    }
}


これだけです。
簡単のために、ドラッグさせるファイルは固定、フルパスで指定しています。

DataObjectを作成し、ドラッグ開始時に渡します。

内部的には、OLE (Object Linking and Embedding) Drag and Dropと呼ばれる、Windowsに組み込まれているシステムを使って、ファイルをやりとりしています。

動作確認

Formアプリをデバッグ実行して、ドラッグできるか確認します。

ラベルをドラッグしようとすると、マウスの形状が🚫に変わります。

ドラッグ開始

さらにフォームの外側までドラッグすると、なにか持っていそうな形状になりました。
ドラッグ外側

エクスプローラーからファイルをドラッグしたときのように、ファイルのアイコン表示することも検討しましたが諦めました。

Formからhtmlにドラッグアンドドロップ

作成したFormアプリから、作成したhtmlに対してファイルをドラッグアンドドロップしてみます。

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

ドラッグアンドドロップでファイルを渡すことができました。

まとめ

日常的な操作であるファイルのドラッグ&ドロップが、ブラウザとWindows Formアプリ間でどのように実現されているかを、サンプルコードを通して解説しました。

ブラウザ側の実装(ドロップ先)

  • drop イベントで処理開始
  • イベントオブジェクトの dataTransfer を通じて取得

Windows Form側の実装(ドラッグ元)

  • DataObject を作成し、ファイルパスの情報を DataFormats.FileDrop 形式で格納
  • ドラッグ操作は DoDragDrop() メソッドで実行

ドラッグ&ドロップを実装するときに、参考にしてみてください。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?