<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
*{
padding: 0;
margin: 0;
}
ul{
list-style:none;
width: 900px;
height: 500px;
margin:50px auto;
}
img{
display:block;
width: 100%;
height: 100%;
}
li{
float:left;
width: 200px;
height: 150px;
margin:10px;
border:1px solid blue;
cursor:move;
}
.active{
border:1px dashed #ccc;
}
</style>
</head>
<body>
<ul id="list">
<li><img src="./img/1.jpg" alt=""></li>
<li><img src="./img/2.jpg" alt=""></li>
<li><img src="./img/3.jpg" alt=""></li>
<li><img src="./img/4.jpg" alt=""></li>
<li><img src="./img/5.jpg" alt=""></li>
<li><img src="./img/6.jpg" alt=""></li>
<li><img src="./img/7.jpg" alt=""></li>
<li><img src="./img/8.jpg" alt=""></li>
<li><img src="./img/9.jpg" alt=""></li>
<li><img src="./img/10.jpg" alt=""></li>
<li><img src="./img/11.jpg" alt=""></li>
<li><img src="./img/12.jpg" alt=""></li>
</ul>
<script src="./base.js"></script>
<script>
/*思路:封装一个拖拽的函数,使每个对象可以实现拖拽
(1)分析:拖拽的实现需要绝对定位脱离文档流
问题:给css设置position:absolute;图片重叠在一处
解决:先通过循环利用每个元素的offsetLeft以及offsetTop记住每个元素的位置,然后赋值给各个元素的left和top值,将所有元素的left和top值设置好之后再给元素脱离文档流 并且清除元素的margin值,循环调用拖拽函数.
(2)如何让元素抬起鼠标的时候回到原来的位置?
解决:调用move函数,move(操作的对象,回到的位置(json对象),回调函数);
问题:位置如何找?
解决:循环把各个元素的位置按照对象的形式{"left":值,"top":值}保存在数组里面,可以通过下标来访到每个元素的位置
(3)层级问题
解决:利用计数器让点击元素层级++;
(4)碰撞检测
思路:封装一个碰撞的函数,返回碰撞最多那个元素的下标(因为咱们要通过下标找位置);
找到两个元素:①拖拽元素obj②碰撞元素(得循坏查找拖拽元素是否占了人家的位置){要除去本身}
找没碰的范围,排除没碰的范围剩下的就是碰了
左:boxL+boxW<objL
右:objL+objW<boxL
上:boxT+boxH<objT
下:objT+objH<boxT
(5)找碰撞最多的元素(即左上角对角线最短的)以及这个元素的下标
问题:因为要检测的碰撞元素时除本身外的其他所有元素
有可能它同时跟好多元素进行碰撞
咱们要在一堆里面找距离最小的
找最小距离的方法:先假设某个数最小完后跟后面一堆数进行比较,如果后面出现比假设的最小数还小的数,那么将这个数赋给最小数,这个l对应哪个元素的下标i赋给最小数的下标
在循环结束找到最小值的下标返回;
在鼠标抬起的时候,调用碰撞的函数bb(obj),将它返回值保存在_index里面
(6)换位置
对象(aLi) 下标 位置(arr)
拖拽元素aLi[index](obj) index arr[index]
碰撞元素aLi[_index] _index arr[_index]
如果没碰到(即返回值-1),回到拖拽元素自己的位置move(obj,arr[index]);
如果碰到了,进行位置交换move(obj,arr[_index])
move(aLi[_index],arr[index])
同时要把保存位置的数组里面的位置进行交换*/
var oList=document.getElementById("list");
var aLi=oList.getElementsByTagName("li");
var zIndex=1;
var arr=[];
for(var i=0;i<aLi.length;i++){
aLi[i].style.left=aLi[i].offsetLeft+"px";
aLi[i].style.top=aLi[i].offsetTop+"px";
arr.push({"left":aLi[i].offsetLeft,"top":aLi[i].offsetTop});
}
for(var i=0;i<aLi.length;i++){
aLi[i].style.position="absolute";
aLi[i].style.margin=0;
getDay(aLi[i],i);
}
function getDay(obj,index){
obj.οnmοusedοwn=function(ev){
obj.style.zIndex=zIndex++;
var evt=ev||window.event;
var dx=evt.offsetX;
var dy=evt.offsetY;
document.οnmοusemοve=function(ev){
var evt=ev||window.event;
var x=evt.clientX;
var y=evt.clientY;
obj.style.left=x-dx+"px";
obj.style.top=y-dy+"px";
ww=PZ(obj);
for(var i=0;i<aLi.length;i++){
aLi[i].className="";
}
if(ww!=-1){
aLi[ww].className="active";
}
return false;
}
document.οnmοuseup=function(){
document.οnmοusemοve=null;
ww=PZ(obj);
if(ww==-1){
move(obj,arr[index]);
}else{
move(obj,arr[ww]);
move(aLi[ww],arr[index]);//元素和位置
//出现问题,都给第一张换位
var timep=arr[index];
arr[index]=arr[ww];
arr[ww]=timep;
for(var i=0;i<aLi.length;i++){
aLi[i].className="";
}
}
return false;
}
}
}
function PZ(obj){
var oL=obj.offsetLeft;
var oT=obj.offsetTop;
var oW=obj.offsetWidth;
var oH=obj.offsetHeight;
var min=100000;
var mIndex=-1;
for(var i=0;i<aLi.length;i++){
//不能跟本身比较
if(aLi[i]==obj){
continue;
}
var aL=aLi[i].offsetLeft;
var aT=aLi[i].offsetTop;
var aW=aLi[i].offsetWidth;
var aH=aLi[i].offsetHeight;
//找一个判断一个
if(oL+oW<aL||oL>aL+aW || oT+oH<aT || oT>aT+aH){
//没碰的
}else{
/*console.log("碰到了"+i);*/
var a=oL-aL;
var b=aT-oT;
var l=Math.sqrt(a*a+b*b);
if(l<min){
min=l;
mIndex=i;
}
}
}
return mIndex;
}
</script>
</body>
</html>