<!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.onmousedown=function(ev){
obj.style.zIndex=zIndex++;
var evt=ev||window.event;
var dx=evt.offsetX;
var dy=evt.offsetY;
document.onmousemove=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.onmouseup=function(){
document.onmousemove=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>