<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
* {margin: 0; padding: 0;}
#ul1 { width: 360px; position: relative; margin: 10px auto; }
#ul1 li{ width: 100px; height: 100px; float: left; list-style: none; margin: 10px; z-index: 1;}
#ul1 .active{ border: 1px dashed red; }
</style>
<script type="text/javascript">
window.onload=function(){
var oUl=document.getElementById(‘ul1‘);
var aLi=oUl.getElementsByTagName(‘li‘);
var aPos=[]; //事先定义一个数组用来把li的位置存起来
var iMinZindex=2; //为了解决层级关系
var i=0;
//布局转换
for(i=0; i<aLi.length; i++){
aPos[i]={
left: aLi[i].offsetLeft,
top: aLi[i].offsetTop
}; //以josn的方式存储每个li位置的坐标
}
for(i=0; i<aLi.length; i++){
aLi[i].style.left=aPos[i].left+‘px‘;
aLi[i].style.top=aPos[i].top+‘px‘;
aLi[i].style.position=‘absolute‘;
aLi[i].style.margin=0;
aLi[i].index=i; //设置每个li的index索引值
} //设置每个li的位置, 不能放在同一个循环里面
//拖拽
for(i=0; i<aLi.length; i++){
setDrag(aLi[i]);
}
function setDrag(obj){
obj.onmousedown=function(ev){
var oEvent=ev||event;
obj.style.zIndex=iMinZindex++;
var disX=oEvent.clientX-obj.offsetLeft;
var disY=oEvent.clientY-obj.offsetTop;
document.onmousemove=function(ev){
var oEvent=ev||event;
obj.style.left=oEvent.clientX-disX+‘px‘;
obj.style.top=oEvent.clientY-disY+‘px‘;
/*for(i=0; i<aLi.length; i++){
aLi[i].className=‘‘; //先清空class
if(obj==aLi[i]) continue; //跳过本身循环 因为和本身检测肯定是碰上的
if(cdTest(obj, aLi[i])){
aLi[i].className=‘active‘;
}
}*/
for(i=0; i<aLi.length; i++){
aLi[i].className=‘‘;
}
var oNer=findNearest(obj);
if(oNer){
oNer.className=‘active‘;
}
};
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
var oNer=findNearest(obj); //找到碰上的,并且找到最近的
if(oNer){ //碰到的时候
oNer.className=‘‘; //让碰见的物体的样式为空
oNer.style.zIndex=iMinZindex++; //为了移动的时候在最上面移动
obj.style.zIndex=iMinZindex++; //为了移动的时候在最上面移动
startMove(oNer, aPos[obj.index]); //被碰到的物体移动到拖拽的这个物体的位置上
startMove(obj, aPos[oNer.index]); //拖拽的物体移动到被碰到的物体oNer的物体上
var tmp=0; //交换index值
tmp=obj.index;
obj.index=oNer.index;
oNer.index=tmp;
}else{ //没有碰到的时候
startMove(obj, aPos[obj.index] /*{left: aPos[obj.index].left, top: aPos[obj.index].top}*/);
//没有碰撞时恢复到原来的位置。利用apos数组事先存好的位置
//aPos 本身就是一个json可以直接用
}
};
clearInterval(obj.timer); //鼠标按下时把原来的定时器先清除掉
return false;
};
};
//碰撞检测
function cdTest(obj1, obj2){ //九宫格原理
var l1=obj1.offsetLeft; //obj1的左边线
var r1=obj1.offsetLeft+obj1.offsetWidth; //obj1的右边线
var t1=obj1.offsetTop; //上边线
var b1=obj1.offsetTop+obj1.offsetHeight; //下边线
var l2=obj2.offsetLeft; //obj1的左边线
var r2=obj2.offsetLeft+obj1.offsetWidth; //obj1的右边线
var t2=obj2.offsetTop; //上边线
var b2=obj2.offsetTop+obj1.offsetHeight; //下边线
if(r1<l2 || l1>r2 || b1<t2 || t1>b2){ //四种上下左右碰不到的情况
return false;
}else{
return true;
}
}
//找到碰上的,并且找到最近的
function findNearest(obj){
var iMin=9999999; //预先定义一个最大值 然后比较比这个小就赋值给他 求最小值
var iMinIndex=-1;
for(i=0; i<aLi.length; i++){
if(obj==aLi[i]) continue; //如果是本身就跳出当次循环
if(cdTest(obj, aLi[i])){ //检测碰上的时候找最近的
var dis=getDis(obj, aLi[i]); //求出距离
if(iMin>dis){ //把最小的赋值给iMin
iMin=dis;
iMinIndex=i; //并且记住位置
}
}
}
if(iMinIndex==-1){ //如何没有改变iMinIndex的值说明没有碰撞任何物体
return null; //返回空
}else{
return aLi[iMinIndex]; //返回最近的那个值
}
}
//计算两点间的距离利用勾股定理
function getDis(obj1, obj2){
var a=obj1.offsetLeft-obj2.offsetLeft; //两个物体的左右距离
var b=obj1.offsetTop-obj2.offsetTop; //两个物体的上下距离
return Math.sqrt(a*a + b*b);
}
};
//运动框架
function getStyle(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
} else{
return getComputedStyle(obj,false)[attr];
}
};
function startMove(obj,json,fn){
clearInterval(obj.timer);
obj.timer = setInterval(function(){
var bStop=true; //这一次运动就结束了,所有值都到达了。
for(var attr in json){
//1.取当前的值
var iCur=0;
if(attr == ‘opacity‘){
iCur=parseInt(parseFloat(getStyle(obj,attr))*100);
} else{
iCur=parseInt(getStyle(obj,attr));
}
//2.算速度
var iSpeed=(json[attr]-iCur)/8;
iSpeed=iSpeed>0?Math.ceil(iSpeed):Math.floor(iSpeed);
//3.检测停止
if(iCur!=json[attr]){
bStop=false;
}
if(attr==‘opacity‘){
obj.style.filter=‘alpha(opacity:‘+(iCur+iSpeed)+‘)‘;
obj.style.opacity=(iCur+iSpeed)/100;
} else{
obj.style[attr]=iCur+iSpeed+‘px‘;
}
}
if(bStop){
clearInterval(obj.timer);
if(fn){
fn();
}
}
},30)
}
//运动框架结束
</script>
</head>
<body>
<ul id="ul1">
<li><img src="images/image01.jpg" width="100" /></li>
<li><img src="images/image02.jpg" width="100" /></li>
<li><img src="images/image03.jpg" width="100" /></li>
<li><img src="images/image04.jpg" width="100" /></li>
<li><img src="images/image05.jpg" width="100" /></li>
<li><img src="images/image01.jpg" width="100" /></li>
<li><img src="images/image02.jpg" width="100" /></li>
<li><img src="images/image03.jpg" width="100" /></li>
<li><img src="images/image04.jpg" width="100" /></li>
<li><img src="images/image05.jpg" width="100" /></li>
<div style="clear: both;"></div>
</ul>
</body>
</html>
原文:http://www.cnblogs.com/qibingshen/p/5410812.html