Last active
August 3, 2021 23:34
-
-
Save uhop/d87365fac38ba6b8cbf0b890d0c2258e to your computer and use it in GitHub Desktop.
A minimalistic generic DnD code. A facelift of https://gist.github.com/uhop/21fa11bf387e234e0d79bf90d7b08735
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>DnD test bed - grouping</title> | |
<link rel="stylesheet" href="./dnd.css" /> | |
</head> | |
<body> | |
<h1>DnD test bed - grouping</h1> | |
<div class="container"> | |
<div class="item dnd-item dnd-handle">One</div> | |
<div class="item dnd-item dnd-handle">Two</div> | |
<div class="item dnd-item dnd-handle">Three</div> | |
<div class="item dnd-item dnd-handle">Four</div> | |
<div class="item dnd-item dnd-handle">Five</div> | |
</div> | |
<p> | |
Lorem ipsum dolor sit amet, odio consul ea pri, has ridens repudiandae ea, pro ex aliquid accusata. Vix te magna iudicabit, in quot nobis has, mel ex | |
ludus melius ocurreret. Ad homero vidisse quo, soluta possim omittam pri in. Eam adhuc erroribus ex, sed lorem delectus liberavisse ad. | |
</p> | |
<p> | |
Nisl integre scriptorem te has, eam te iisque denique qualisque. Mei laudem aperiam facilisi ut, id altera tritani recteque nam, est id vitae facilisi | |
evertitur. Democritum repudiandae ea ius. Duo cu tritani invenire, ius illum alterum phaedrum eu, nec officiis interesset ei. Mei elit disputationi ad. | |
</p> | |
<p> | |
Te quidam labitur abhorreant usu. Habeo deseruisse ut eum, usu ei unum tractatos. Id est ferri movet nostrum, nullam platonem periculis no quo. Falli | |
vivendum at vis, amet possim moderatius et pri. Salutandi instructior mei ut, augue quidam necessitatibus mel id. Mutat primis qui ex, adipisci quaestio | |
eu duo, at sea wisi causae periculis. | |
</p> | |
<p> | |
Per summo debitis ut. Quem mucius constituam mel ut, eos quodsi animal appetere ex. At doming nostrud vel, inani voluptatum no sed. Et vis exerci vidisse | |
praesent, eam impedit definitionem ea, apeirian vituperatoribus sed no. | |
</p> | |
<p> | |
Nec augue dolor laoreet ad. Ut eos perfecto nominati. Dolorum appellantur id sed, vis probatus constituam appellantur ea. Cu animal alterum molestie has. | |
Tempor praesent tincidunt eu ius, ei oportere posidonium comprehensam pri. | |
</p> | |
<script type="module"> | |
import DndMove from './dnd.js'; | |
document.addEventListener('DOMContentLoaded', () => { | |
DndMove.start(document.querySelector('.container'), { | |
init: mover => { | |
DndMove.init(mover); | |
mover.avatar.classList.remove('dnd-target'); | |
}, | |
moving: DndMove.movingY, | |
over: DndMove.over, | |
drop: mover => { | |
if (mover.previousOverItem) { | |
if (mover.previousOverItem !== mover.node) { | |
let target = mover.previousOverItem.parentNode.classList.contains('dnd-target') ? mover.previousOverItem.parentNode : mover.previousOverItem; | |
if (target.classList.contains('dnd-item')) { | |
target = target.ownerDocument.createElement('div'); | |
target.classList.add('dnd-target'); | |
mover.previousOverItem.classList.remove('dnd-target'); | |
mover.previousOverItem.parentNode.replaceChild(target, mover.previousOverItem); | |
target.appendChild(mover.previousOverItem); | |
} | |
mover.node.classList.remove('dnd-target'); | |
const parent = mover.node.parentNode; | |
target.appendChild(mover.node); | |
if (!parent.firstElementChild) { | |
parent.parentNode.removeChild(parent); | |
} | |
} | |
} else { | |
const parent = mover.node.parentNode; | |
mover.container.appendChild(mover.node); | |
if (!parent.firstElementChild) { | |
parent.parentNode.removeChild(parent); | |
} | |
} | |
} | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>DnD test bed - horizontal</title> | |
<link rel="stylesheet" href="./dnd.css" /> | |
</head> | |
<body> | |
<h1>DnD test bed - horizontal</h1> | |
<div class="horizontal container"> | |
<div class="item dnd-item dnd-handle">One</div> | |
<div class="item dnd-item dnd-handle">Two</div> | |
<div class="item dnd-item dnd-handle">Three</div> | |
<div class="item dnd-item dnd-handle">Four</div> | |
<div class="item dnd-item dnd-handle">Five</div> | |
</div> | |
<p> | |
Lorem ipsum dolor sit amet, odio consul ea pri, has ridens repudiandae ea, pro ex aliquid accusata. Vix te magna iudicabit, in quot nobis has, mel ex | |
ludus melius ocurreret. Ad homero vidisse quo, soluta possim omittam pri in. Eam adhuc erroribus ex, sed lorem delectus liberavisse ad. | |
</p> | |
<p> | |
Nisl integre scriptorem te has, eam te iisque denique qualisque. Mei laudem aperiam facilisi ut, id altera tritani recteque nam, est id vitae facilisi | |
evertitur. Democritum repudiandae ea ius. Duo cu tritani invenire, ius illum alterum phaedrum eu, nec officiis interesset ei. Mei elit disputationi ad. | |
</p> | |
<p> | |
Te quidam labitur abhorreant usu. Habeo deseruisse ut eum, usu ei unum tractatos. Id est ferri movet nostrum, nullam platonem periculis no quo. Falli | |
vivendum at vis, amet possim moderatius et pri. Salutandi instructior mei ut, augue quidam necessitatibus mel id. Mutat primis qui ex, adipisci quaestio | |
eu duo, at sea wisi causae periculis. | |
</p> | |
<p> | |
Per summo debitis ut. Quem mucius constituam mel ut, eos quodsi animal appetere ex. At doming nostrud vel, inani voluptatum no sed. Et vis exerci vidisse | |
praesent, eam impedit definitionem ea, apeirian vituperatoribus sed no. | |
</p> | |
<p> | |
Nec augue dolor laoreet ad. Ut eos perfecto nominati. Dolorum appellantur id sed, vis probatus constituam appellantur ea. Cu animal alterum molestie has. | |
Tempor praesent tincidunt eu ius, ei oportere posidonium comprehensam pri. | |
</p> | |
<script type="module"> | |
import DndMove from './dnd.js'; | |
document.addEventListener('DOMContentLoaded', () => { | |
DndMove.start(document.querySelector('.container'), { | |
init: DndMove.init, | |
over: DndMove.over, | |
moving: DndMove.movingX, | |
drop: DndMove.dropX | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>DnD test bed - handle</title> | |
<link rel="stylesheet" href="./dnd.css" /> | |
</head> | |
<body> | |
<h1>DnD test bed - handle</h1> | |
<div class="container"> | |
<div class="item dnd-item"><span class="dnd-handle">⋮⋮</span> One</div> | |
<div class="item dnd-item"><span class="dnd-handle">⋮⋮</span> Two</div> | |
<div class="item dnd-item"><span class="dnd-handle">⋮⋮</span> Three</div> | |
<div class="item dnd-item"><span class="dnd-handle">⋮⋮</span> Four</div> | |
<div class="item dnd-item"><span class="dnd-handle">⋮⋮</span> Five</div> | |
</div> | |
<p> | |
Lorem ipsum dolor sit amet, odio consul ea pri, has ridens repudiandae ea, pro ex aliquid accusata. Vix te magna iudicabit, in quot nobis has, mel ex | |
ludus melius ocurreret. Ad homero vidisse quo, soluta possim omittam pri in. Eam adhuc erroribus ex, sed lorem delectus liberavisse ad. | |
</p> | |
<p> | |
Nisl integre scriptorem te has, eam te iisque denique qualisque. Mei laudem aperiam facilisi ut, id altera tritani recteque nam, est id vitae facilisi | |
evertitur. Democritum repudiandae ea ius. Duo cu tritani invenire, ius illum alterum phaedrum eu, nec officiis interesset ei. Mei elit disputationi ad. | |
</p> | |
<p> | |
Te quidam labitur abhorreant usu. Habeo deseruisse ut eum, usu ei unum tractatos. Id est ferri movet nostrum, nullam platonem periculis no quo. Falli | |
vivendum at vis, amet possim moderatius et pri. Salutandi instructior mei ut, augue quidam necessitatibus mel id. Mutat primis qui ex, adipisci quaestio | |
eu duo, at sea wisi causae periculis. | |
</p> | |
<p> | |
Per summo debitis ut. Quem mucius constituam mel ut, eos quodsi animal appetere ex. At doming nostrud vel, inani voluptatum no sed. Et vis exerci vidisse | |
praesent, eam impedit definitionem ea, apeirian vituperatoribus sed no. | |
</p> | |
<p> | |
Nec augue dolor laoreet ad. Ut eos perfecto nominati. Dolorum appellantur id sed, vis probatus constituam appellantur ea. Cu animal alterum molestie has. | |
Tempor praesent tincidunt eu ius, ei oportere posidonium comprehensam pri. | |
</p> | |
<script type="module"> | |
import DndMove from './dnd.js'; | |
document.addEventListener('DOMContentLoaded', () => { | |
DndMove.start(document.querySelector('.container'), { | |
init: DndMove.init, | |
over: DndMove.over, | |
moving: DndMove.movingY, | |
drop: DndMove.dropY | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>DnD test bed - reorder</title> | |
<link rel="stylesheet" href="./dnd.css" /> | |
</head> | |
<body> | |
<h1>DnD test bed - reorder</h1> | |
<div class="container"> | |
<div class="item dnd-item dnd-handle">One</div> | |
<div class="item dnd-item dnd-handle">Two</div> | |
<div class="item dnd-item dnd-handle">Three</div> | |
<div class="item dnd-item dnd-handle">Four</div> | |
<div class="item dnd-item dnd-handle">Five</div> | |
</div> | |
<p> | |
Lorem ipsum dolor sit amet, odio consul ea pri, has ridens repudiandae ea, pro ex aliquid accusata. Vix te magna iudicabit, in quot nobis has, mel ex | |
ludus melius ocurreret. Ad homero vidisse quo, soluta possim omittam pri in. Eam adhuc erroribus ex, sed lorem delectus liberavisse ad. | |
</p> | |
<p> | |
Nisl integre scriptorem te has, eam te iisque denique qualisque. Mei laudem aperiam facilisi ut, id altera tritani recteque nam, est id vitae facilisi | |
evertitur. Democritum repudiandae ea ius. Duo cu tritani invenire, ius illum alterum phaedrum eu, nec officiis interesset ei. Mei elit disputationi ad. | |
</p> | |
<p> | |
Te quidam labitur abhorreant usu. Habeo deseruisse ut eum, usu ei unum tractatos. Id est ferri movet nostrum, nullam platonem periculis no quo. Falli | |
vivendum at vis, amet possim moderatius et pri. Salutandi instructior mei ut, augue quidam necessitatibus mel id. Mutat primis qui ex, adipisci quaestio | |
eu duo, at sea wisi causae periculis. | |
</p> | |
<p> | |
Per summo debitis ut. Quem mucius constituam mel ut, eos quodsi animal appetere ex. At doming nostrud vel, inani voluptatum no sed. Et vis exerci vidisse | |
praesent, eam impedit definitionem ea, apeirian vituperatoribus sed no. | |
</p> | |
<p> | |
Nec augue dolor laoreet ad. Ut eos perfecto nominati. Dolorum appellantur id sed, vis probatus constituam appellantur ea. Cu animal alterum molestie has. | |
Tempor praesent tincidunt eu ius, ei oportere posidonium comprehensam pri. | |
</p> | |
<script type="module"> | |
import DndMove from './dnd.js'; | |
document.addEventListener('DOMContentLoaded', () => { | |
DndMove.start(document.querySelector('.container'), { | |
init: DndMove.init, | |
over: DndMove.over, | |
moving: DndMove.movingY, | |
newOver: mover => { | |
if (!mover.previousOverItem || mover.previousOverItem === mover.node) return; | |
// move the dragged node | |
let beforeNode = mover.previousOverItem; | |
for (let current = mover.container.firstElementChild; current; current = current.nextElementSibling) { | |
if (current === mover.node) { | |
beforeNode = beforeNode.nextElementSibling; | |
break; | |
} | |
if (current === mover.previousOverItem) break; | |
} | |
mover.container.insertBefore(mover.node, beforeNode); | |
// recalculate bounding boxes | |
mover.calculateBoundingBoxes(); | |
}, | |
drop: () => {} | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.container { | |
font-size: 18pt; | |
color: black; | |
display: flex; | |
flex-direction: column; | |
margin: 2em; | |
border: 3px solid #ddd; | |
padding: 1em; | |
max-width: 8em; | |
} | |
.container.horizontal { | |
flex-direction: row; | |
max-width: auto; | |
} | |
.item { | |
font-size: 18pt; | |
color: black; | |
flex: 1 1 auto; | |
margin: 0.5em; | |
border: 3px solid #ccc; | |
padding: 1em; | |
} | |
.dnd-handle { | |
cursor: pointer; | |
} | |
.dnd-handle::selection { | |
background-color: transparent; | |
} | |
.dnd-avatar { | |
background-color: #fcc; | |
opacity: 0.5; | |
} | |
.dnd-dragged { | |
background-color: #cfc; | |
opacity: 0.5; | |
} | |
.dnd-over { | |
background-color: #ffe; | |
} | |
body { | |
transition: background-color 0.5s; | |
} | |
.dnd-in-flight body { | |
background-color: #ddd; | |
} | |
.dnd-dragged-container { | |
background-color: white; | |
} | |
/* grouping extension */ | |
.dnd-target { | |
margin: 0.5em; | |
} | |
.dnd-target .dnd-item { | |
margin: 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>DnD test bed</title> | |
<link rel="stylesheet" href="./dnd.css" /> | |
</head> | |
<body> | |
<h1>DnD test bed</h1> | |
<div class="container"> | |
<div class="item dnd-item dnd-handle">One</div> | |
<div class="item dnd-item dnd-handle">Two</div> | |
<div class="item dnd-item dnd-handle">Three</div> | |
<div class="item dnd-item dnd-handle">Four</div> | |
<div class="item dnd-item dnd-handle">Five</div> | |
</div> | |
<p> | |
Lorem ipsum dolor sit amet, odio consul ea pri, has ridens repudiandae ea, pro ex aliquid accusata. Vix te magna iudicabit, in quot nobis has, mel ex | |
ludus melius ocurreret. Ad homero vidisse quo, soluta possim omittam pri in. Eam adhuc erroribus ex, sed lorem delectus liberavisse ad. | |
</p> | |
<p> | |
Nisl integre scriptorem te has, eam te iisque denique qualisque. Mei laudem aperiam facilisi ut, id altera tritani recteque nam, est id vitae facilisi | |
evertitur. Democritum repudiandae ea ius. Duo cu tritani invenire, ius illum alterum phaedrum eu, nec officiis interesset ei. Mei elit disputationi ad. | |
</p> | |
<p> | |
Te quidam labitur abhorreant usu. Habeo deseruisse ut eum, usu ei unum tractatos. Id est ferri movet nostrum, nullam platonem periculis no quo. Falli | |
vivendum at vis, amet possim moderatius et pri. Salutandi instructior mei ut, augue quidam necessitatibus mel id. Mutat primis qui ex, adipisci quaestio | |
eu duo, at sea wisi causae periculis. | |
</p> | |
<p> | |
Per summo debitis ut. Quem mucius constituam mel ut, eos quodsi animal appetere ex. At doming nostrud vel, inani voluptatum no sed. Et vis exerci vidisse | |
praesent, eam impedit definitionem ea, apeirian vituperatoribus sed no. | |
</p> | |
<p> | |
Nec augue dolor laoreet ad. Ut eos perfecto nominati. Dolorum appellantur id sed, vis probatus constituam appellantur ea. Cu animal alterum molestie has. | |
Tempor praesent tincidunt eu ius, ei oportere posidonium comprehensam pri. | |
</p> | |
<script type="module"> | |
import DndMove from './dnd.js'; | |
document.addEventListener('DOMContentLoaded', () => { | |
DndMove.start(document.querySelector('.container'), { | |
init: DndMove.init, | |
over: DndMove.over, | |
moving: DndMove.movingY, | |
drop: DndMove.dropY | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const noop = () => {}; | |
class DndMove { | |
static supportedEvents = { | |
mouseup: 'onMouseUp', | |
mousemove: 'onMouseMove', | |
touchend: 'onMouseUp', | |
touchcancel: 'onMouseUp', | |
touchmove: 'onTouchMove', | |
dragstart: 'stopEvent', | |
selectstart: 'stopEvent' | |
}; | |
static formNode = {a: 1, input: 1, select: 1, button: 1, textarea: 1, option: 1}; | |
constructor(container, options, node, e) { | |
this.container = container; | |
this.options = options || {}; | |
this.node = node; | |
// handle the state | |
this.container.classList.add('dnd-dragged-container'); | |
this.node.ownerDocument.documentElement.classList.add('dnd-in-flight'); | |
this.node.classList.add('dnd-dragged'); | |
this.mouseX = e.pageX; | |
this.mouseY = e.pageY; | |
this.avatar = (this.options.makeAvatar || DndMove.clone)(this); | |
this.moving = this.options.moving || DndMove.moving; | |
this.over = this.options.over || noop; | |
this.newOver = this.options.newOver || noop; | |
// listen for events | |
Object.keys(DndMove.supportedEvents).forEach(name => name != 'selectstart' && this.node.ownerDocument.addEventListener(name, this)); | |
this.node.ownerDocument.body.addEventListener('selectstart', this); | |
(this.options.init || noop)(this); | |
} | |
destroy() { | |
// remove event listeners | |
Object.keys(DndMove.supportedEvents).forEach(name => name != 'selectstart' && this.node.ownerDocument.removeEventListener(name, this)); | |
this.node.ownerDocument.body.removeEventListener('selectstart', this); | |
// handle the state | |
this.container.classList.remove('dnd-dragged-container'); | |
this.node.ownerDocument.documentElement.classList.remove('dnd-in-flight'); | |
this.node.classList.remove('dnd-dragged'); | |
if (this.previousOverItem) { | |
this.previousOverItem.classList.remove('dnd-over'); | |
} | |
(this.options.destroy || noop)(this); | |
} | |
calculateBoundingBoxes() { | |
const items = this.container.querySelectorAll(this.options.target || '.dnd-item'); | |
this.itemBoxes = Array.from(items).map(item => { | |
const rect = item.getBoundingClientRect(); | |
return { | |
node: item, | |
left: rect.left + window.pageXOffset, | |
right: rect.right + window.pageXOffset, | |
top: rect.top + window.pageYOffset, | |
bottom: rect.bottom + window.pageYOffset | |
}; | |
}); | |
} | |
// the starter | |
static start(container, options) { | |
options = options || {}; | |
const callback = DndMove.process(container, options), | |
filter = options.filter || '.dnd-handle'; | |
let handler = typeof filter == 'function' ? e => filter(e) && callback(e) : e => e.target.closest(filter) && callback(e); | |
container.addEventListener('mousedown', handler); | |
container.addEventListener('touchstart', handler); | |
return { | |
container, | |
options, | |
remove: () => { | |
container.removeEventListener('mousedown', handler); | |
container.removeEventListener('touchstart', handler); | |
} | |
}; | |
} | |
// events | |
handleEvent(e) { | |
this[DndMove.supportedEvents[e.type]](e); | |
} | |
onMouseUp(e) { | |
// done | |
DndMove.stopEvent(e); | |
(this.options.drop || noop)(this); | |
this.avatar.parentNode.removeChild(this.avatar); | |
this.destroy(); | |
} | |
onMouseMove(e) { | |
DndMove.stopEvent(e); | |
this.moving(this, e); | |
this.mouseX = e.pageX; | |
this.mouseY = e.pageY; | |
this.avatar.style.left = this.x + 'px'; | |
this.avatar.style.top = this.y + 'px'; | |
this.over(this); | |
} | |
onTouchMove(e) { | |
DndMove.stopEvent(e); | |
const fakeEvent = e.targetTouches[0]; | |
this.moving(this, fakeEvent); | |
this.mouseX = fakeEvent.pageX; | |
this.mouseY = fakeEvent.pageY; | |
this.avatar.style.left = this.x + 'px'; | |
this.avatar.style.top = this.y + 'px'; | |
this.over(this); | |
} | |
stopEvent(e) { | |
DndMove.stopEvent(e); | |
} | |
// helpers | |
static init(mover) { | |
// container box | |
let style = window.getComputedStyle(mover.container); | |
const rect = mover.container.getBoundingClientRect(), | |
box = { | |
left: rect.left + window.pageXOffset + parseFloat(style.borderLeftWidth), | |
right: rect.right + window.pageXOffset - parseFloat(style.borderRightWidth) - parseFloat(style.marginRight), | |
top: rect.top + window.pageYOffset + parseFloat(style.borderTopWidth), | |
bottom: rect.bottom + window.pageYOffset - parseFloat(style.borderBottomWidth) - parseFloat(style.marginBottom) | |
}; | |
style = window.getComputedStyle(mover.avatar); | |
box.left -= parseFloat(style.marginLeft); | |
box.right -= parseFloat(style.marginLeft) + parseFloat(style.borderLeftWidth) + parseFloat(style.width) + parseFloat(style.borderRightWidth); | |
box.top -= parseFloat(style.marginTop); | |
box.bottom -= parseFloat(style.marginTop) + parseFloat(style.borderTopWidth) + parseFloat(style.height) + parseFloat(style.borderBottomWidth); | |
mover.containerBox = box; | |
mover.calculateBoundingBoxes(); | |
} | |
static over(mover) { | |
// binary search is better, but linear will do in a pinch | |
const done = mover.itemBoxes.some(item => { | |
if (item.left <= mover.mouseX && mover.mouseX < item.right && item.top <= mover.mouseY && mover.mouseY < item.bottom) { | |
if (item.node !== mover.previousOverItem) { | |
mover.previousOverItem && mover.previousOverItem.classList.remove('dnd-over'); | |
mover.previousOverItem = item.node; | |
mover.previousOverItem.classList.add('dnd-over'); | |
mover.newOver(mover); | |
} | |
return true; | |
} | |
return false; | |
}); | |
if (!done && mover.previousOverItem) { | |
mover.previousOverItem && mover.previousOverItem.classList.remove('dnd-over'); | |
mover.previousOverItem = null; | |
mover.newOver(mover); | |
} | |
} | |
static movingX(mover, e) { | |
mover.x += e.pageX - mover.mouseX; | |
mover.x = Math.max(mover.containerBox.left, Math.min(mover.containerBox.right, mover.x)); | |
} | |
static movingY(mover, e) { | |
mover.y += e.pageY - mover.mouseY; | |
mover.y = Math.max(mover.containerBox.top, Math.min(mover.containerBox.bottom, mover.y)); | |
} | |
static moving(mover, e) { | |
mover.x += e.pageX - mover.mouseX; | |
mover.x = Math.max(mover.containerBox.left, Math.min(mover.containerBox.right, mover.x)); | |
mover.y += e.pageY - mover.mouseY; | |
mover.y = Math.max(mover.containerBox.top, Math.min(mover.containerBox.bottom, mover.y)); | |
} | |
static dropX(mover) { | |
if (!mover.previousOverItem) return; | |
// binary search is better, but linear will do in a pinch | |
const done = mover.itemBoxes.some(item => { | |
if (mover.mouseX < (item.left + item.right) / 2) { | |
item.node !== mover.node && mover.container.insertBefore(mover.node, item.node); | |
return true; | |
} | |
return false; | |
}); | |
!done && mover.container.appendChild(mover.node); | |
} | |
static dropY(mover) { | |
if (!mover.previousOverItem) return; | |
// binary search is better, but linear will do in a pinch | |
const done = mover.itemBoxes.some(item => { | |
if (mover.mouseY < (item.top + item.bottom) / 2) { | |
item.node !== mover.node && mover.container.insertBefore(mover.node, item.node); | |
return true; | |
} | |
return false; | |
}); | |
!done && mover.container.appendChild(mover.node); | |
} | |
// statics | |
static process(container, options) { | |
return e => { | |
e.preventDefault(); | |
const node = e.target; | |
if (!e.button && DndMove.formNode[node.tagName.toLowerCase()] !== 1 && !node.classList.contains('dnd-ignore')) { | |
const item = node.closest('.dnd-item'); | |
if (item && !item.classList.contains('dnd-ignore')) { | |
new DndMove(container, options, item, e); | |
} | |
} | |
}; | |
} | |
static clone(mover) { | |
const node = mover.node, | |
box = node.getBoundingClientRect(), | |
style = window.getComputedStyle(node), | |
avatar = node.cloneNode(true); | |
mover.x = box.left - parseFloat(style.marginLeft) + window.pageXOffset; | |
mover.y = box.top - parseFloat(style.marginTop) + window.pageYOffset; | |
avatar.style.position = 'absolute'; | |
avatar.style.height = style.height; | |
avatar.style.width = style.width; | |
avatar.style.left = mover.x + 'px'; | |
avatar.style.top = mover.y + 'px'; | |
avatar.classList.remove('dnd-dragged'); | |
avatar.classList.add(mover.options.avatarClass || 'dnd-avatar'); | |
node.ownerDocument.body.appendChild(avatar); | |
return avatar; | |
} | |
static stopEvent(e) { | |
e.preventDefault(); | |
e.stopPropagation(); | |
} | |
} | |
export default DndMove; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment