<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style>
ul{
list-style:none;
padding-bottom:20px;
}
.item{
cursor: pointer;
height:24px;
line-height:24px;
background-color:#9c9c9c;
border:1px solid #d9d9d9;
border-radius:4px;
color:#fff;
padding:10px;
}
</style>
</head>
<body>
<div id="app">
<ul
@dragstart="onDragStart"
@dragover="onDragOver"
@dragend="onDragEnd"
ref="parentNode">
<li
v-for="(item,index) in data"
:key="index"
class="item"
draggable="true"
>{{item}}</li>
</ul>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
data:[1,2,3,4,5,6],
draging:null,//被拖拽的對(duì)象
target:null,//目標(biāo)對(duì)象
},
mounted () {
//為了防止火狐瀏覽器拖拽的時(shí)候以新標(biāo)簽打開(kāi)缺狠,此代碼真實(shí)有效
document.body.ondrop = function (event) {
event.preventDefault();
event.stopPropagation();
}
},
methods:{
onDragStart(event){
console.log("drag start")
this.draging=event.target;
},
onDragOver(event){
console.log('drag move')
this.target=event.target;
let targetTop=event.target.getBoundingClientRect().top;
let dragingTop=this.draging.getBoundingClientRect().top;
if (this.target.nodeName === "LI"&&this.target !== this.draging) {
if (this.target) {
if (this.target.animated) {
return;
}
}
if(this._index(this.draging)<this._index(this.target)){
this.target.parentNode.insertBefore(this.draging,this.target.nextSibling);
}else{
this.target.parentNode.insertBefore(this.draging, this.target);
}
this._anim(targetTop,this.target);
this._anim(dragingTop,this.draging);
}
},
_anim(startPos,dom){
let offset=startPos-dom.getBoundingClientRect().top;
dom.style.transition="none";
dom.style.transform=`translateY(${offset}px)`;
//觸發(fā)重繪
dom.offsetWidth;
dom.style.transition="transform .3s";
dom.style.transform=``;
//觸發(fā)重繪
// setTimeout(()=>{
// dom.style.transition="transform .3s";
// dom.style.transform=``;
// },0)
clearTimeout(dom.animated);
dom.animated=setTimeout(()=>{
dom.style.transition="";
dom.style.transform=``;
dom.animated=false;
},300)
},
onDragEnd(event){
console.log('drag end')
let currentNodes=Array.from(this.$refs.parentNode.childNodes);
let data=currentNodes.map((i,index)=>{
let item=this.data.find(c=>c==i.innerText);
return item
});
console.log(data)
},
_index(el){
let domData=Array.from(this.$refs.parentNode.childNodes);
return domData.findIndex(i=>i.innerText==el.innerText);
}
}
})
</script>
</html>
VueDND