拖拽排序的实现示例demo
拖拽排序的实现示例demo
- 文章说明
- 核心代码
- 示例效果展示
文章说明
文章主要为了学习拖拽排序的实现思路,并且采用此示例效果来进一步理解Flip动画的使用
参考渡一前端袁老师的讲解视频
核心代码
页面源码,拖拽排序的实现代码并不复杂,但是可以很好的帮助学习该示例的实现思路和拖拽API的使用
<!DOCTYPE html>
<html lang="zh-cn"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>拖拽排序</title><style>* {box-sizing: border-box;}.container {margin: 100px auto auto;width: 200px;}.container div {height: 30px;line-height: 30px;margin: 10px 0;background-color: chocolate;border-radius: 10px;color: #ffffff;text-align: center;}.container .moving {border: dashed 1px black;background-color: #ffffff;}</style></head><body><div class="container"><div draggable="true" class="item">1</div><div draggable="true" class="item">2</div><div draggable="true" class="item">3</div><div draggable="true" class="item">4</div><div draggable="true" class="item">5</div><div draggable="true" class="item">6</div></div><script src="flip.js"></script><script>const container = document.getElementsByClassName("container")[0];let dragElem = null;let flip;container.ondragstart = function (e) {flip = new Flip(container.children, 0.5);dragElem = e.target;setTimeout(() => {e.target.classList.add("moving");}, 0);}container.ondragover = function (e) {e.preventDefault();}container.ondragend = function (e) {e.target.classList.remove("moving");}container.ondragenter = function (e) {e.preventDefault();if (e.target === container || dragElem === e.target) {return;}const children = [...container.children];const sourceIndex = children.indexOf(dragElem);const targetIndex = children.indexOf(e.target);if (sourceIndex > targetIndex) {container.insertBefore(dragElem, e.target);} else {container.insertBefore(dragElem, e.target.nextElementSibling);}flip.play();}</script></body>
</html>
Flip工具类
class Flip {children = null;delay = 0;constructor(children, delay = 1) {this.children = children;this.calculatePos();this.delay = delay;}calculatePos(name = "first") {const children = this.children;for (let i = 0; i < children.length; i++) {children[i][name] = children[i].getBoundingClientRect();}}play() {this.calculatePos("last");const children = this.children;for (let i = 0; i < children.length; i++) {const first = children[i]["first"];const last = children[i]["last"];if (first.x !== last.x || first.y !== last.y) {children[i].style.transform = `translateY(${first.y - last.y}px) translateX(${first.x - last.x}px)`;setTimeout(() => {children[i].style.transition = `transform ${this.delay}s`;children[i].style.removeProperty("transform");setTimeout(() => {children[i].style.removeProperty("transition");this.calculatePos();}, this.delay * 1000);}, 0);}}}
}
示例效果展示
拖拽功能展示