ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Drag and Drop API とは
HTML5 Drag and Drop API(DnD API)は、ブラウザがネイティブでサポートするドラッグ&ドロップ機構です。要素を別の場所にマウス/タッチで運んだり、デスクトップからファイルをブラウザに投げ込んだりできます。jQuery UI や独自実装に頼らずに、純粋な DOM イベントだけで実現できるのが利点です。
基本フロー
| 段階 | 発火イベント | 対象 | 主な処理 |
|---|---|---|---|
| 掴む | dragstart | ドラッグ元 | dataTransfer.setData() でデータをセット |
| 運ぶ | drag | ドラッグ元 | 連続発火。UI 演出に使う |
| 上を通過 | dragenter / dragover | ドロップ先 | preventDefault() 必須 |
| 離脱 | dragleave | ドロップ先 | ホバー演出を解除 |
| 離す | drop | ドロップ先 | dataTransfer.getData() で受け取り |
| 終了 | dragend | ドラッグ元 | クリーンアップ |
最小実装例
<div id="src" draggable="true" style="padding:1em;background:#cef">Drag me</div>
<div id="dst" style="padding:2em;border:2px dashed #999;margin-top:1em">Drop here</div>
<script>
const src = document.getElementById('src');
const dst = document.getElementById('dst');
src.addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text/plain', 'hello');
e.dataTransfer.effectAllowed = 'move';
});
dst.addEventListener('dragover', (e) => {
e.preventDefault(); // ← これが無いと drop が発火しない
e.dataTransfer.dropEffect = 'move';
});
dst.addEventListener('drop', (e) => {
e.preventDefault();
const data = e.dataTransfer.getData('text/plain');
dst.textContent = 'Dropped: ' + data;
});
</script>
dataTransfer オブジェクト
ドラッグ元とドロップ先の間でデータを受け渡すのが event.dataTransfer です。
| プロパティ / メソッド | 用途 |
|---|---|
setData(type, value) | データを格納。type は MIME(text/plain, text/html, application/json 等) |
getData(type) | データ取得。drop ハンドラ内でのみ |
files | OS から D&D されたファイル(FileList) |
effectAllowed | 許可される動作 copy / move / link / all |
dropEffect | カーソル表示(copy/move/link/none) |
setDragImage(el, x, y) | ドラッグ中のサムネ画像を差し替え |
ファイルの D&D(最頻出ユースケース)
<div id="dropzone" style="padding:3em;border:2px dashed #888;text-align:center">
Drop files here
</div>
<script>
const zone = document.getElementById('dropzone');
['dragenter', 'dragover'].forEach(t => {
zone.addEventListener(t, (e) => {
e.preventDefault();
zone.style.background = '#eef';
});
});
['dragleave', 'drop'].forEach(t => {
zone.addEventListener(t, (e) => {
e.preventDefault();
zone.style.background = '';
});
});
zone.addEventListener('drop', async (e) => {
const files = e.dataTransfer.files; // FileList
for (const f of files) {
console.log(f.name, f.size, f.type);
// 例: 画像をプレビュー
if (f.type.startsWith('image/')) {
const url = URL.createObjectURL(f);
const img = new Image();
img.src = url;
zone.appendChild(img);
}
// 例: サーバへアップロード
const fd = new FormData();
fd.append('file', f);
await fetch('/upload', { method: 'POST', body: fd });
}
});
</script>
preventDefault を忘れる罠
仕様上、ブラウザはデフォルトでは「ドロップを禁止する」動作になっています。dragover で preventDefault() を呼ばないと drop イベントが発火しません。これが Drag and Drop API で最も多いハマりどころです。
// ❌ NG: drop が発火しない
dst.addEventListener('drop', handler);
// ✅ OK
dst.addEventListener('dragover', (e) => e.preventDefault());
dst.addEventListener('drop', handler);
並べ替え(ソート)UI の実装
<ul id="list">
<li draggable="true">Apple</li>
<li draggable="true">Banana</li>
<li draggable="true">Cherry</li>
</ul>
<script>
let dragEl = null;
document.querySelectorAll('#list li').forEach(li => {
li.addEventListener('dragstart', () => { dragEl = li; li.style.opacity = .4; });
li.addEventListener('dragend', () => { dragEl = null; li.style.opacity = 1; });
li.addEventListener('dragover', (e) => {
e.preventDefault();
const rect = li.getBoundingClientRect();
const after = (e.clientY - rect.top) > rect.height / 2;
li.parentNode.insertBefore(dragEl, after ? li.nextSibling : li);
});
});
</script>
フォールバック / 制約
- モバイル(iOS Safari など)はネイティブ DnD 非対応に近い。Pointer Events や touch イベントで自前実装が必要
- キーボード操作・スクリーンリーダー対応が弱い → アクセシビリティ重視なら
dnd-kitを採用 dataTransfer.setData('text/uri-list', url)で URL D&D に対応- セキュリティ上、別オリジン間でのファイルパス取得は禁止
モダンライブラリの選び方
| ライブラリ | 用途 | 特徴 |
|---|---|---|
| SortableJS | リスト並べ替え | Vanilla JS、フレームワーク非依存、軽量 |
| dnd-kit | React | アクセシビリティ良好、Tree / Kanban 対応、ヘッドレス |
| react-dnd | React | 古参、HTML5 backend と touch backend を切替 |
| vue.draggable.next | Vue 3 | SortableJS のラッパー |
| Interact.js | 汎用 | リサイズ・ジェスチャ込み、低レイヤ |
FAQ
Q: drop イベントが発火しません
A: 99% は dragover の preventDefault() 忘れです。dragenter でも入れておくと確実。
Q: スマホでドラッグできません
A: HTML5 DnD はモバイルでは動作が不安定です。SortableJS(touch サポートあり)や Pointer Events を用いた自前実装に切り替えてください。
Q: ドラッグ中の見た目を変えたい
A: dragstart で e.dataTransfer.setDragImage(canvasEl, 0, 0)。canvas に好きな画像を描いて差し替えます。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- Canvas API
- Drag and Drop API
- History API
- WebStorage API
- File API
- System Information API
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- IPv6とは|128bitアドレス・コロン16進表記/::省略・リンクローカル・SLAAC・デュアルスタック NEW 2026-06-22 12:34:44
- MAC アドレスフィルタリングの仕組みと限界 | ネットワーク入門 NEW 2026-06-22 12:19:10
- VPNとは|暗号トンネル・サイト間/リモートアクセス・IPsec/SSL-VPN/WireGuardを解説 NEW 2026-06-22 12:19:10
- WebRTC とは ブラウザ間 P2P の音声・映像・データ通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/2 とは 多重化・HPACK・バイナリフレーム | ネットワーク入門 NEW 2026-06-22 12:17:25
- Web通信プロトコル入門 HTTP/2・HTTP/3・WebSocket・gRPC・WebRTC | ネットワーク入門 NEW 2026-06-22 12:17:25
- gRPC とは HTTP/2 + Protocol Buffers の高速 RPC | ネットワーク入門 NEW 2026-06-22 12:17:25
- HTTP/3 (QUIC) とは UDP ベースの低遅延 Web 通信 | ネットワーク入門 NEW 2026-06-22 12:17:25
- WebSocket とは 全二重リアルタイム通信 ws/wss | ネットワーク入門 NEW 2026-06-22 12:17:25
- 証明書と認証局(CA)とは|X.509・信頼チェーン・DV/OV/EV・失効(CRL/OCSP)を解説 NEW 2026-06-22 12:17:24
- ファイアウォールとは|パケットフィルタ・ステートフル・DMZ・次世代FW(L4/L7)を解説 NEW 2026-06-22 12:17:24
- iptables/nftablesとは|テーブル・チェーン・ルール例・永続化をLinux視点で解説 NEW 2026-06-22 12:17:24
- HAProxy とは frontend/backend と設定例 | ネットワーク入門 NEW 2026-06-22 12:17:24
- CDN とは エッジキャッシュ・TTL・Cloudflare/CloudFront | ネットワーク入門 NEW 2026-06-22 12:17:24
- TLS/SSLの仕組み|ハンドシェイク・暗号スイート・前方秘匿性・証明書検証をわかりやすく解説 NEW 2026-06-22 12:17:24
コメントを削除してもよろしいでしょうか?