<template>
<div class="wrap">
<div class="list-wrap">
<div id="list" class="list">
<div :id="item" class="list-item" draggable="true" v-for="item of list" :key="item">
{{ item }}
</div>
</div>
</div>
<div class="drag-place">
<div id="drop" class="input"></div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: new Array(100).fill(0).map((item, index) => index + 1)
}
},
mounted() {
let dragResult = false,
el = null,
parent = document.getElementById('list');
// 拖动元素的事件设置
let list = document.getElementsByClassName('list')[0];
let arr_li = document.getElementsByClassName('list-item');
for (let i = 0; i < arr_li.length; i++) {
arr_li[i].ondragstart = function(ev) {
this.className = 'list-item opacity';
el = document.getElementById(ev.target.id)
}
// 拖动过程中触发
arr_li[i].ondrag = function() {}
// 拖动结束触发
arr_li[i].ondragend = function(ev) {
const target = ev.target;
// 通过一个全局变量判断是否拖放成功
if (!dragResult) {
// 拖放失败把opacity状态去除
target.className = 'list-item';
} else {
list.removeChild(target);
dragResult = false;
}
}
// 放置元素的事件设置
arr_li[i].ondragover = function(ev) {
ev.preventDefault();
const target = ev.target;
if (el.id === ev.target.id) {
return
}
if (ev.pageY - target.offsetTop > target.offsetHeight / 2) {
// 不能先移除,这样会导致offsetTop的高度计算出现偏差
parent.removeChild(el)
parent.insertBefore(el, target.nextSibling);
} else {
parent.removeChild(el)
parent.insertBefore(el, target);
}
}
arr_li[i].ondrop = (ev) => {
ev.preventDefault();
ev.stopPropagation();
el = null;
}
}
}
}
</script>
<style>
* {
margin: 0;
padding: 0;
}
.opacity {
opacity: 0.2;
}
.wrap {
display: flex;
}
.list-wrap {
width: 300px;
height: 600px;
flex: 1
}
.list {
width: 100%;
}
.list-item {
width: 100%;
height: 50px;
line-height: 20px;
border: 1px solid red;
margin-top: 20px;
}
.drag-place {
flex: 1;
}
.input {
width: 50%;
min-height: 30px;
float: right;
border: 1px solid red;
}
.block {
width: 20px;
line-height: 20px;
border: 1px solid lightblue;
}
</style>
效果图如下