JSFiddle - React, Tailwind, and code Playground
by Andy You
HTML
<div class="columns">
<div class="column" id="col-1">
<div class="overlay" draggable="true"></div>
<header id="header-1" draggable="false">A</header>
</div>
<div class="column" id="col-2">
<div class="overlay" draggable="true"></div>
<header id="header-2" draggable="false">B</header>
</div>
<div class="column" id="col-3">
<div class="overlay" draggable="true"></div>
<header id="header-3" draggable="false">C</header>
</div>
</div>
SCSS
/**
* 防止可以被拖移的元素內部的文字被選取造成局部拖移
*/
[draggable] {
-moz-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
/**
* 舊版 WebKit 需要此設定讓元素可以被拖移
*/
-khtml-user-drag: element;
-webkit-user-drag: element;
}
.column {
width: 150px;
height: 150px;
float: left;
border: 10px solid pink;
background-color: pink;
margin-right: 5px;
text-align: center;
cursor: move;
position: relative;
box-sizing: border-box;
background-origin: border-box;
margin-top: -10px;
margin-bottom: -10px;
.overlay {
position: absolute;
top: 0;
left: 0;
width: 150px;
height: 150px;
background: rgba(255, 255, 0, .5);
}
header {
text-shadow: #fff 0 1px;
}
&.over {
border: 10px dashed gray;
}
}
Babel + JSX
var columns = document.querySelectorAll('.columns .column')
;[...columns].forEach( (col) => {
col.addEventListener('dragstart', dragStart, false)
col.addEventListener('dragover', dragOver, false)
col.addEventListener('dragenter', dragEnter, false)
col.addEventListener('dragleave', dragLeave, false)
col.addEventListener('drop', drop, false)
col.addEventListener('dragend', dragEnd, false)
/*;[...col.childNodes].forEach((el) => {
el.addEventListener('dragsover', (e) => {
console.log('child execute start', e.target.id);
e.stopPropagation();
e.preventDefault();
return false;
}, false)
el.addEventListener('dragenter', (e) => {
console.log('child execute enter', e.target.id);
e.stopPropagation();
e.preventDefault();
return false;
}, false)
})*/
})
var dragSrcEl;
function dragStart (e) {
console.log('drag start')
this.style.opacity = .4
dragSrcEl = this
e.dataTransfer.effectAllowed = 'move'
e.dataTransfer.setData('text/html', this.innerHTML)
}
function dragOver (e) {
if (e.preventDefault) {
// 觸發 drop 需要這行
e.preventDefault()
}
return false
}
function dragEnter (e) {
console.log('enter')
this.classList.add('over')
this.parentNode.insertBefore(this, dragSrcEl)
}
function dragLeave (e) {
console.log('leave')
this.classList.remove('over')
}
function drop (e) {
if (e.stopPropagation) {
e.stopPropagation()
}
if (dragSrcEl != this) {
dragSrcEl.innerHTML = this.innerHTML
this.innerHTML = e.dataTransfer.getData('text/html')
}
return false
}
function dragEnd (e) {
this.style.opacity = 1
;[...columns].forEach( (col) => {
col.classList.remove('over')
})
}
function _css (el, prop, val) {
var style = el && el.style
if (style) {
if (val === void 0) {
if (document.defaultView && document.defaultView.getComputedStyle) {
val = document.defaultView.getComputedStyle(el, '');
} else if (el.currentStyle)...