上一次寫了拖拽,其實主要仍是想實現拖拽以後實現自動排列,跟手機屏幕那樣移動圖標能夠自動排列,先看效果:html
很常見的一個效果,先說一下思路:數組
每個元素都是絕對定位,初始化的時候是經過js去排列。bash
拖拽使用的方法跟上一篇文章如出一轍。ui
定義了一個數組,每一個元素的字段:spa
{el: elArr[i], sort: i, index: i}code
el是這個元素,用於排列,也就是改變top和left,sort是元素排列的位置,index是當前元素的index,不會改變。cdn
拖拽的時候,當鼠標點擊選中當前的元素的時候,這個元素移動,當移動到另外一個元素一半的時候,至關於要替換這個元素,我是以這樣一個方法判斷移動到哪個位置:htm
let moveIndex = Math.round(x / 125) + Math.round(y / 125) * 5;排序
我元素的寬度和距離的寬度和是125,因此移動距離超過一半就四捨五入算加1,列方向也是同樣,超過1那麼元素就是要加一行的個數。ip
我定義了一個當前的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>
複製代碼