
drag.gif
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.wrapper {
width: 200px;
box-sizing: border-box;
margin: 10px 0;
height: 50px;
overflow: hidden;
}
[draggable="true"] {
height: 50px;
background-color: coral;
}
</style>
</head>
<body>
<div id="test">
<div class="wrapper">
<div draggable="true">A</div>
</div>
<div class="wrapper">
<div draggable="true">B</div>
</div>
<div class="wrapper">
<div draggable="true">C</div>
</div>
<div class="wrapper">
<div draggable="true">D</div>
</div>
</div>
<script>
var dragged
function show_wrapper(target) {
target.parentNode.style.border = "thick dashed gray"
}
function hidden_wrapper(target) {
target.parentNode.style.border = ""
}
function set_draging_target(target) {
target.style.opacity = '0.5'
}
function restore_draging_target(target) {
target.style.opacity = ''
}
var created_wrapper = null
function delete_created_wrapper() {
if (created_wrapper && created_wrapper.childNodes.length == 0 && created_wrapper.parentNode) {
created_wrapper.parentNode.removeChild(created_wrapper)
}
}
function create_wrapper() {
delete_created_wrapper()
var wrapper = document.createElement('div')
wrapper.className = 'wrapper'
wrapper.style.border = "thick dashed gray"
return wrapper
}
function isFrontOf(a, b) {
if (a == null || b == null)
return false
if (a.nextSibling == b)
return true
return isFrontOf(a.nextSibling, b)
}
function isBehindOf(a, b) {
if (a == null || b == null)
return false
if (a.previousSibling == b)
return true
return isBehindOf(a.previousSibling, b)
}
function pSibling(a, b) {
if (b == null || b.previousSibling == null)
return false
if (a == b.previousSibling)
return true
if (b.previousSibling.nodeName == 'DIV')
return false
return pSibling(a, b.previousSibling)
}
function nSibling(a, b) {
if (b == null || b.nextSibling == null)
return false
if (a == b.nextSibling)
return true
if (b.nextSibling.nodeName == 'DIV')
return false
return nSibling(a, b.nextSibling)
}
document.addEventListener("dragend", function (event) {
restore_draging_target(dragged)
hidden_wrapper(dragged)
}, false);
document.addEventListener('dragstart', event => {
dragged = event.target
set_draging_target(dragged)
show_wrapper(dragged)
})
document.addEventListener('dragleave', event => {
event.preventDefault()
var leaved = event.target
if (leaved == dragged || leaved == dragged.parentNode)
return
})
document.addEventListener("dragover", function (event) {
event.preventDefault();
var dropped = event.target
if (dragged == dropped)
return
if (!dropped.draggable)
return
var target_height = dropped.getBoundingClientRect().height
var over_top_part = event.offsetY < target_height / 2
var over_bottom_part = event.offsetY >= target_height / 2
// 拖拽到下一个item的上半部分时
if (pSibling(dragged.parentNode, dropped.parentNode))
if (over_top_part) {
return
}
// 拖拽到上一个item的下半部分时
if (nSibling(dragged.parentNode, dropped.parentNode))
if (over_bottom_part) {
return
}
if (over_top_part) {
var new_wrapper = create_wrapper()
dropped.parentNode.parentNode.insertBefore(new_wrapper, dropped.parentNode)
created_wrapper = new_wrapper
dragged.parentNode.style.display = "none"
}
if (over_bottom_part) {
var new_wrapper = create_wrapper()
dropped.parentNode.parentNode.insertBefore(new_wrapper, dropped.parentNode.nextSibling)
created_wrapper = new_wrapper
dragged.parentNode.style.display = "none"
}
}, false)
document.addEventListener("drop", function (event) {
event.preventDefault();
var dropped = event.target
if (dropped == dragged)
return
if (created_wrapper && created_wrapper.parentNode) {
dragged.parentNode.parentNode.removeChild(dragged.parentNode)
created_wrapper.appendChild(dragged)
created_wrapper = null
return
}
if (dropped.className.indexOf('wrapper') == -1) {
delete_created_wrapper()
dragged.parentNode.style.display = ""
return
}
var target_height = dropped.getBoundingClientRect().height
var over_top_part = event.offsetY < target_height / 2
var over_bottom_part = event.offsetY >= target_height / 2
// 放置到下一个item的上半部分时
if (pSibling(dragged.parentNode, dropped.parentNode))
if (over_top_part) {
console.log('1')
return
}
// 放置到上一个item的下半部分时
if (nSibling(dragged.parentNode, dropped.parentNode))
if (over_bottom_part) {
console.log('2')
return
}
// 先移除原先位置的元素
dragged.parentNode.parentNode.removeChild(dragged.parentNode)
dropped.appendChild(dragged)
}, false);
document.addEventListener('dragenter', event => {
event.preventDefault()
})
</script>
</body>
</html>
网友评论