共计 1935 个字符,预计需要花费 5 分钟才能阅读完成。
之前在我的项目中用到了拖放排序,不过是用 react-dnd 实现的,因为集体还是比拟喜爱这种拖放的交互体验的,所以写了个小 demo。
不废话,先看看最终实现的样子:
我称之为《鬼灭之圣诞之拖拽排序????》:)
用鬼灭的图做了个九宫格,可拖放任意一张调整九张图的程序。
实现过程
首先把页面构造和款式写好:
index.html
<div id="container">
<img draggable="true" src="./img/1.jpg">
<img draggable="true" src="./img/2.jpg">
<img draggable="true" src="./img/3.jpg">
<img draggable="true" src="./img/4.jpg">
<img draggable="true" src="./img/5.jpg">
<img draggable="true" src="./img/6.jpg">
<img draggable="true" src="./img/7.jpg">
<img draggable="true" src="./img/8.jpg">
<img draggable="true" src="./img/9.jpg">
</div>
index.css
#container{
margin: 0 auto;
overflow: hidden;
width: 420px;
}
#container img{
width: 120px;
height: 120px;
object-fit: cover; // 图片放弃原有尺寸比例,可能被裁剪
float: left;
border: 10px solid #ffffff;
cursor: move; // 光标款式
}
对于拖放
写排序功能前,须要先理解一下咱们拖放 API:
在 HTML5 规范施行之前,拖拽也是被宽泛应用的,web 开发者将 click、mouseover,mousemove 组合起来实现拖放逻辑,过程略显冗余和繁琐。
在 HTML5 中,拖放成为了规范的一部分,只需将元素 draggable 属性设为 true,就可能拖放元素。拖放流程大抵如下图(省略了 dragleave 和 dragexit):
HTML5 不仅仅定义了拖拽的事件类型,还在事件对象中标准了一个重量级的对象:dataTransfer
。借助它能够实现 数据传输 、 拖拽图案设定 、 拖拽文件上传 ,可通过event.dataTransfer
来拜访该对象。
增加拖放事件
因为拖动是实时的,所以没有应用 drop
而是应用了 dragover
。并且用一个变量来保留以后拖动的元素。这里应用事件委托,间接应用#container
来监听。
const node = document.querySelector('#container');
let dragging = null; // 拖动的对象
// 拖拽开始
node.ondragstart = (e) => {
//firefox 设置了 setData 后元素能力拖动
e.dataTransfer.setData('for-firefox', 'hello')
dragging = e.target;
let offsetX = parseFloat(getComputedStyle(e.target).width)/2;
let offsetY = parseFloat(getComputedStyle(e.target).height)/2;
e.dataTransfer.setDragImage(e.target ,offsetX,offsetY);
}
// 被拖拽的元素在某个元素停留时
node.ondragover = (e) => {e.preventDefault();
let target = e.target; // 停留的某个元素
if (target.nodeName === "IMG" && target !== dragging) {if (getIndex(dragging) < getIndex(target)) {target.parentNode.insertBefore(dragging, target.nextSibling);
} else {target.parentNode.insertBefore(dragging, target);
}
}
}
// 获取元素在父元素中的索引
function getIndex(el) {
let index = 0;
if (!el || !el.parentNode) {return -1;}
while (el && (el = el.previousElementSibling)) {index++;}
return index;
}
OK,这样根本的排序就做好了,如果感觉图片切换过于僵硬的话,还能够增加一些动画成果,让过渡再平滑一些。
正文完
发表至: javascript
2020-12-24