上一次写了拖拽, 其实主要还是想实现拖拽之后实现自动排列, 跟手机屏幕那样移动图标可以自动排列, 先看效果:
image
很常见的一个效果, 先说一下思路:
每一个元素都是绝对定位, 初始化的时候是通过 JS 去排列.
拖拽使用的方法跟上一篇文章一模一样.
定义了一个数组, 每个元素的字段:
{el: elArr[i], sort: i, index: i}
el 是这个元素, 用于排列, 也就是改变 top 和 left,sort 是元素排列的位置, index 是当前元素的 index, 不会改变.
拖拽的时候, 当鼠标点击选中当前的元素的时候, 这个元素移动, 当移动到另一个元素一半的时候, 相当于要替换这个元素, 我是以这样一个方法判断移动到哪一个位置:
let moveIndex = Math.round(x / 125) + Math.round(y / 125) * 5;
我元素的宽度和距离的宽度和是 125, 所以移动距离超过一半就四舍五入算加 1, 列方向也是一样, 超过 1 那么元素就是要加一行的个数.
我定义了一个当前的 index, 如果移动到的 index 不等于初始化的 index, 那么就是要发生移动, 当从大移动到小, 在这个范围内的, 所有排序都要加 1, 其他不变, 如果从小移动到大, 这个范围内排序都要减 1, 其他不变. 然后当前的排序替换那个. 还要判断, 如果移动计算出来的 index 小于 0 就等于 0, 大于当前最大值就等于当前最大值.
选中当前要改变 index, 置于最上方, 移动用的是 transition 使得缓和的变换, 但是移动当前要使 transition 为 0 秒, 否则延迟会脱离当前元素.
还是上代码, 运行之后看看代码就很清楚了:
- <!DOCTYPE html>
- <HTML>
- <head>
- <title>
- </title>
- <style>
- *{ padding:0; margin:0; } HTML, body{ width:100%; height:100%; } .wrap{
- position: relative; width: 600px; height: 600px; margin: 100px auto; border:
- solid 1px red; } .wrap div{ position:absolute; z-index: 1; width:100px;
- height:100px; background: red; transition: all .5s; }
- </style>
- </head>
- <body>
- <div class="wrap" id="elWrap">
- <div>
- 1
- </div>
- <div>
- 2
- </div>
- <div>
- 3
- </div>
- <div>
- 4
- </div>
- <div>
- 5
- </div>
- <div>
- 6
- </div>
- <div>
- 7
- </div>
- <div>
- 8
- </div>
- <div>
- 9
- </div>
- <div>
- 10
- </div>
- </div>
- <script>
- let index = 0;
- let elArr = document.getElementById('elWrap').children;
- let elList = [];
- // 构造一个数组
- for (let i = 0; i < elArr.length; i++) {
- elList.push({
- el: elArr[i],
- sort: i,
- index: i
- });
- elList[i].onclick = addEvent(elList[i]);
- }
- moveItem(elList);
- function addEvent(item) {
- item.el.addEventListener('mousedown', (e) = >{
- item.el.style.zIndex = 2;
- item.el.style.transition = 'all 0s';
- let startX = e.pageX,
- startY = e.pageY,
- left = item.el.offsetLeft,
- top = item.el.offsetTop;
- let moveFun = (e) = >{
- let X = e.pageX - startX + left;
- let Y = e.pageY - startY + top;
- item.el.style.left = `$ {
- X
- }
- px`;
- item.el.style.top = `$ {
- Y
- }
- px`;
- reRange(item, X, Y);
- };
- document.addEventListener('mousemove', moveFun);
- item.el.addEventListener('mouseup', () = >{
- document.removeEventListener('mousemove', moveFun);
- item.el.style.zIndex = 1;
- item.el.style.transition = 'all .5s';
- moveItem(elList);
- });
- });
- }
- function reRange(item, x, y) {
- let moveIndex = Math.round(x / 125) + Math.round(y / 125) * 5;
- moveIndex = moveIndex < 0 ? 0 : moveIndex;
- moveIndex = moveIndex > elList.length - 1 ? elList.length - 1 : moveIndex;
- if (moveIndex != index) {
- index = moveIndex;
- let currentSort = item.sort;
- for (let i = 0; i < elList.length; i++) {
- if (currentSort < moveIndex) {
- if (elList[i].sort > currentSort && elList[i].sort <= moveIndex) {
- elList[i].sort -= 1;
- };
- } else if (currentSort > moveIndex) {
- if (elList[i].sort < currentSort && elList[i].sort >= moveIndex) {
- elList[i].sort += 1;
- };
- }
- };
- elList[item.index].sort = moveIndex;
- moveItem(elList);
- }
- }
- // 排列
- function moveItem(elList) {
- for (let i = 0; i < elList.length; i++) {
- elList[i].el.style.left = elList[i].sort % 5 * 125 + 'px';
- elList[i].el.style.top = parseInt(elList[i].sort / 5) * 125 + 'px';
- }
- }
- </script>
- </body>
- </HTML>
image
来源: http://www.jianshu.com/p/24965ad1413a