二话不说先上图
效果就是这样,感兴趣,走起! github源码在 这里
先看下需求
- 按下后选中图片背景色变为深蓝色,被碰撞的图片背景色变红,位置变化完成后颜色变成原始色
- 没有碰撞,位置复原;多个碰撞和接触面积最大的交换位置
- 交换位置时,选中的图片在最上层划过去
别废话,告诉我怎么实现
- 图片绝对定位,记录鼠标点下去后的起始位置和抬起位置,通过修改图片的
top
和left
值完成移动 - 鼠标按下记录下鼠标位置和选中图片的位置,柯里化处理
this
指向 - 浏览器默认元素是不能拖拽的,想要拖拽就得取消浏览器的默认行为
event.preventDefault
- 拖拽开始时改变被选中图片的
z-Index
确保在其他图片上移动 - 移动过程中检测有无和其他图片的碰撞,有,改变碰撞图片的背景色
- 拖拽结束,和接触面积最大的图片交换位置或者回原来位置
页面结构
<ul class="box" id="box">
<li><img src="./img/1.png" alt=""></li>
<li><img src="./img/2.png" alt=""></li>
<li><img src="./img/3.png" alt=""></li>
<li><img src="./img/4.png" alt=""></li>
<li><img src="./img/5.png" alt=""></li>
<li><img src="./img/6.png" alt=""></li>
<li><img src="./img/7.png" alt=""></li>
<li><img src="./img/8.png" alt=""></li>
<li><img src="./img/9.png" alt=""></li>
</ul>
复制代码
页面初始化
为了方便,操作DOM我用的jquery
let boxList = $('#box>li');
let zIndex = 0;
//进入页面先记录下每个图片的初始位置,并绑定事件
for (let i = boxList.length - 1; i >= 0; i--) { // 为了防止float塌陷,从最后一张图片开始设置CSS属性
let curLi = boxList[i];
// 记录下最开始的top和left值
curLi.originTop = curLi.offsetTop;
curLi.originLeft = curLi.offsetLeft;
$(curLi).css({
position: "absolute",
margin: 0, //绝对定位的时候就不需要margin了
top: curLi.originTop,
left: curLi.originLeft
});
$(curLi).on("mousedown", down);
$(curLi).on("dragstart", increaseIndex);
$(curLi).on("dragstart", preventDefault);
$(curLi).on("drag", boxMove);
$(curLi).on("drag", preventDefault);
$(curLi).on("dragend", changePos);
$(curLi).on("dragend", preventDefault);
}
复制代码
如果不太清楚offsetTop,offsetLeft,e.pageX,e.pageY
可以参考 这里
更多源码猛戳 这里