<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.list-complete-item {
width: 200px;
height: 200px;
border-radius: 6px;
background: #ccc;
cursor: move;
margin: 6px;
transition: all .2s;
}
.current {
box-shadow: 0 0 20px #000;
transition: all .2s;
transform: scale(1.05);
}
</style>
</head>
<body>
<div id="app"></div>
<script>
class drag {
constructor(ele, dataArray) {
this.dataArray = dataArray;
this.element = ele;
this.children = null;
this.toIndex = null;
this.currentIndex = null;
this.currentNode = null;
this.move = {
x: 0,
y: 0,
move: false
};
this.create();
}
create() {
this.element.innerHTML = this.dataArray.map(e => `<div>${e}</div>`).join(' ');
this.init();
}
init() {
this.children = [...this.element.children];
this.children.forEach((item, i) => {
item.onmousedown = this.onMouseDown.bind(this);
item.classList.add("list-complete-item");
});
}
onMouseDown(e) {
this.currentNode = this.getNode(e, ".list-complete-item")[0];
this.currentNode.setAttribute("draggable", "true");
this.currentNode.ondragend = this.onMouseUp.bind(this);
this.currentNode.ondragstart = this.onMouseStart.bind(this);
}
onMouseStart(e) {
e.dataTransfer.setData("who", e.target);
this.children.forEach((v, i) => {
if (v == this.currentNode) this.currentIndex = i;
v.ondragenter = e => {
v.classList.add("current");
this.toIndex = this.children.findIndex(k => v == k);
};
v.ondragleave = () => {
v.classList.remove("current");
};
});
}
onMouseUp(e) {
let a = this.dataArray[this.currentIndex];
let b = this.dataArray[this.toIndex];
if (a == b) return;
this.dataArray.splice(this.toIndex, 1, a);
this.dataArray.splice(this.currentIndex, 1, b);
this.currentNode.removeAttribute("draggable");
// 拖拽后重新生成节点内容
this.create();
// Vue封装组件需要使用外部 this 。
// that.$emit("inpit", this.dataArray);
// that.$emit("change", {
// current: {
// index: this.currentIndex,
// data: a
// },
// target: {
// index: this.toIndex,
// data: b
// }
// });
}
getNode(e, select) {
var a = e.path || e.composedPath();
let sele = "";
if (select) {
/^[a-zA-Z]+$/g.test(select) ? (sele = "target") : (sele = select.slice(0, 1));
switch (sele) {
case ".":
a = [...a].filter(k => {
if (k.getAttribute && k.getAttribute("class")) {
return (
k.getAttribute("class").indexOf(select.slice(1)) != -1
);
}
});
break;
case "#":
a = [...a].filter(k => {
if (k.id) {
return k.id == select.slice(1);
}
});
break;
case "target":
a = [...a].filter(k => {
if (k.nodeName) {
return k.nodeName.toLowerCase() == select.toLowerCase();
}
});
break;
default:
a = select + "is not defined";
}
} else {
a = [...a].filter(k => {
if ([...e.currentTarget.children].indexOf(k) >= 0) return true;
})[0];
}
return a;
}
}
var a = new drag(document.querySelector('#app'), [1, 2, 3, 4]);
</script>
</body>
</html>
网友评论