这次的列表拖拽模型主要模仿的就是简书后台写文章里面的功能。上个例子九宫格拖拽只是这次的一个例外。研究完上个模型再写这个就更简单了,随便划拉两下就完成了。
实现的思路:
依然是以拖拽模型为基础,相对于九宫格拖拽,这个加入了过渡动画,并且让交换盒子动作发生在移动事件之中。这时候就得把移动盒子的位置单独拿出来,放在鼠标抬起事件结束的地方。另外值得注意的地方,必须的加一个锁,为什么呢?原因好简单,当我们移动的时候,满足条件的时候,另一个盒子就会发生改变,假如移动的方向是往上的,盒子改变的过程有时间过渡,这时候我们移动的盒子还没完全离开盒子,这时候又满足判断条件,盒子反向运动,又回来了。加一个锁让本次盒子运动完成之后在打开锁进行运动。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>列表拖拽模型</title>
<style>
*{margin:0;padding:0;}
body{
background-color: #000;
}
ul{
list-style:none;
height: 850px;
width: 400px;
border-radius: 5px;
margin:20px auto;
position: relative;
border:1px solid red;
}
ul li {
position: absolute;
width: 400px;
height: 100px;
background-color: #fff;
border-radius: 10px;
margin-top: 10px;
box-shadow: 1px 1px 1px #07c160;
cursor:pointer;
}
h3{
width: 400px;
line-height: 100px;
text-align:center;
color:#07c160;
font-size: 24px;
}
/*拖拽的时候让拖拽的图片置于其他图片上面*/
.active{
z-index: 1;
}
</style>
</head>
<body>
<ul>
<li><h3>第一张</h3></li>
<li><h3>第二张</h3></li>
<li><h3>第三张</h3></li>
<li><h3>第四张</h3></li>
<li><h3>第五张</h3></li>
<li><h3>第六张</h3></li>
</ul>
</body>
</html>
<script>
//得到元素
var uls = document.querySelector("ul");
var lis = uls.querySelectorAll("li");
// 批量添加监听
for(var i = 0;i < lis.length;i++){
// 批量放置li盒子
lis[i].style.top = i * 105 + "px";
// 闭包的影响属性法备份每个监听事件的i
lis[i].index = i;
lis[i].onmousedown = function(event){
// 兼容IE
event = event || window.event;
// 鼠标到每个li盒子内层最顶端和最左端的位置
var lisx = event.clientX - this.offsetLeft;
var lisy = event.clientY - this.offsetTop;
// 备份this
var self = this;
// 一个锁,防止事件重复触发
var lock = true;
// 鼠标移动
document.onmousemove = function(event){
// 移除掉每个触发li的transition动作
self.style.transition = "";
// 兼容IE
event = event || window.event;
// li盒子到它的offsetparent的距离,就是离li最近定位的盒子
lisL = event.clientX - lisx;
lisT = event.clientY - lisy;
// 拖拽的时候让拖拽的图片置于其他图片上面更改图片的显示权重
self.className = "active";
//改变移动盒子的定位,做到鼠标跟随
self.style.left = lisL + "px";
self.style.top = lisT + "px";
// 批量遍历每个盒子是否满足交换条件
for(var j = 0;j < lis.length;j++){
// 交换盒子的条件
if(lis[j].offsetTop + lis[j].offsetHeight > self.offsetTop && lis[j].offsetTop < self.offsetTop){
if(lock){
// 事件触发就自锁不在改变
lock = false;
// console.log(self.index);
// 交换两个盒子备份的index
var temp = lis[j].index;
lis[j].index = self.index;
self.index = temp;
// 交换完成去改变盒子的top值
lis[j].style.top = lis[j].index * 105 + "px";
// 同时添加过渡属性
lis[j].style.transition = "all 0.3s ease 0s";
// 当动画运动完成,使用定时器来打开锁。
setTimeout(()=>lock = true,300);
break;
}
}
}
}
// 鼠标抬起事件
document.onmouseup = function(event){
// 移出鼠标移动事件
document.onmousemove = null;
// 去除图片显示权重
self.className = "";
// 改变移动盒子的位置
self.style.left = 0;
self.style.top = self.index * 105 + "px";
}
// 阻止浏览器的默认事件
return false;
}
}
</script>