Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Drag & Drop APIのDataTransferを使ってみる
Search
mame_daifuku
February 20, 2025
0
2
Drag & Drop APIのDataTransferを使ってみる
サンプルアプリ:
https://dnd-sample-two.vercel.app/
リポジトリ:
https://github.com/hiroshi-kato/dnd-sample
mame_daifuku
February 20, 2025
Tweet
Share
Featured
See All Featured
A Soul's Torment
seathinner
1
2.1k
How to make the Groovebox
asonas
2
1.9k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.4k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
210
Art, The Web, and Tiny UX
lynnandtonic
304
21k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.3k
Six Lessons from altMBA
skipperchong
29
4.1k
Amusing Abliteration
ianozsvald
0
80
Automating Front-end Workflow
addyosmani
1371
200k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
1
210
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.1k
Typedesign – Prime Four
hannesfritz
42
2.9k
Transcript
Drag & Drop APIのDataTransferを使ってみる 発表者: Saul
1. 動機 react-dndって何してるんだろう const [{ opacity }, dragRef] = useDrag(
() => ({ type: ItemTypes.CARD, item: { text }, collect: (monitor) => ({ opacity: monitor.isDragging() ? 0.5 : 1 }) }),[]) const [, drop] = useDrop( () => ({ accept: ItemTypes.KNIGHT, drop: () => moveKnight(x, y) }),[x, y])
2. Drag & Drop APIおさらい
D&Dの歴史 古代: JavaScriptで独自実装されていた 現代(2014年): HTML5のAPIとして標準化 仕様書はこちら
属性 draggable <p id="p1" draggable="true">この要素はドラッグできます。</p>
イベント
インターフェース
3. dataTransfer に触れてみる ケース1:ドロップできるアイテムを制限する ケース2:ドラッグ中のアイテムを変更する サンプルアプリ
ケース1:ドロップできるアイテムを制限する // ドラッグ開始時に Todo の情報を dataTransfer にセットする const handleDragStart =
(e: DragEvent<HTMLLIElement>, todo: Todo) => { e.dataTransfer.setData('application/json', JSON.stringify(todo)); e.dataTransfer.effectAllowed = 'move'; }; // ドロップ時に、対象リストと Todo の list プロパティが一致するかチェック const handleDrop = (e: DragEvent<HTMLDivElement>, targetList: 'A' | 'B') => { e.preventDefault(); const data = e.dataTransfer.getData('application/json'); if (data) { const todo: Todo = JSON.parse(data); if (todo.list === targetList) { if (targetList === 'A') { setDroppedA(prev => [...prev, todo]); } else { setDroppedB(prev => [...prev, todo]); } } else { alert(`この Todo アイテムは ${todo.list} 用です。こちらのリストにはドロップできません。`); } } };
ケース2:ドラッグ中のアイテムを変更する const handleDragStart = (e: DragEvent<HTMLLIElement>, todo: Todo) => {
e.dataTransfer.setData('application/json', JSON.stringify(todo)); e.dataTransfer.effectAllowed = 'move'; // カスタムのドラッグイメージを作成 const dragImage = document.createElement('div'); dragImage.className = 'p-2 bg-black text-white rounded text-sm w-32 text-center'; dragImage.innerText = `Dragging: ${todo.text}`; // 一時的にドキュメントに追加してドラッグイメージに設定 document.body.appendChild(dragImage); e.dataTransfer.setDragImage(dragImage, dragImage.offsetWidth / 2, dragImage.offsetHeight / 2); // ドラッグ開始直後に削除 setTimeout(() => document.body.removeChild(dragImage), 0); };
まとめ react-dndって何してるんだろう わかる気がする!!! const [{ opacity }, dragRef] = useDrag(
() => ({ type: ItemTypes.CARD, item: { text }, collect: (monitor) => ({ opacity: monitor.isDragging() ? 0.5 : 1 }) }),[]) const [, drop] = useDrop( () => ({ accept: ItemTypes.KNIGHT, drop: () => moveKnight(x, y) }),[x, y])
おしまい
参考文献 MDN Web Docs: Drag and Drop API W3C: HTML5
仕様書 react-dnd