自动吸附拖拽js

这个效果要注意几点:

1.注意碰撞检测。

2.注意两个元素之间的距离,原理是根据三角形定理。

废话不多说,有不明白的地方可以qq我或者留言,大家一起讨论,谢谢!

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>

<style type="text/css">
*{ padding:0; margin:0}
ul,li{ list-style:none}
.box{ width:311px; border:3px solid #000; margin:50px 200px; overflow:hidden;zoom:1; }
.box ul{ width:305px; overflow:hidden;zoom:1; position:relative; height:450px}
.box ul li{ width:90px; background:#06C; float:left; height:100px; font-weight:bolder; color:#FFF; font-size:24px; text-align:center; margin:5px; line-height:100px}
.cur{ cursor:move;}
.hig{ border:2px dotted #FFFFFF}

</style>

</head>
<body>
<div class="box"  id="moveBox">
   <ul>
 		<li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
        <li>8</li>
        <li>9</li>
        <li>10</li>
        <li>11</li>
        <li>12</li>
       
  

</ul>
<script>
var oBox=document.getElementById("moveBox");
var oUl=oBox.getElementsByTagName("ul")[0];
var oLi=oUl.getElementsByTagName("li");
var aPos = [];
var zx=0;

//布局转换
for (var i = 0; i < oLi.length; i++)
{
	oLi[i].index = i;
	oLi[i].style.top = oLi[i].offsetTop + "px";	
	oLi[i].style.left = oLi[i].offsetLeft + "px";
	aPos.push({"left":oLi[i].offsetLeft, "top":oLi[i].offsetTop})
}	

for(var i=0;i<oLi.length;i+=1){
   oLi[i].style.position="absolute";
	drap(oLi[i]);
}


//拖拽函数
function  drap(obj){
   
    obj.οnmοusedοwn=function(e){
					var oNear=null;
				  var ev=e||window.event;
				  var disX=ev.clientX-this.offsetLeft-oUl.offsetLeft;
				  var disY=ev.clientY-this.offsetTop-oUl.offsetTop;
				  this.className="cur";
				  this.style.zIndex=zx++;
					if(obj.setCapture){
								 obj.setCapture(); 						 
					}else{
						  window.captureEvents(Event.MOUSEMOVE);
					}
					ev.cancelBubble = true;//阻止事件冒泡,防止冲突
		
				  
				document.οnmοusemοve=function(e){
					var ev=e||window.event;
					var w=ev.clientX-disX-oUl.offsetLeft;
					var h=ev.clientY-disY-oUl.offsetTop;		
					(w<0)&&(w=0);
					(w>=(oUl.offsetWidth-obj.offsetWidth))&&(w=(oUl.offsetWidth-obj.offsetWidth));
					(h<0)&&(h=0);
					(h>=(oUl.offsetHeight-obj.offsetHeight))&&(w=(oUl.offsetHeight-obj.offsetHeight));
					
					obj.style.top=h+"px";
					obj.style.left=w+"px";
					for(var i=0;i<oLi.length;i++){
						oLi[i].className="";
					}
				    oNear=findObj(obj);
					oNear && (oNear.className="hig");
					
					
				}
					document.οnmοuseup=function(){
						 if(obj.releaseCapture){
							 obj.releaseCapture(); 
						 }else{
							 window.releaseEvents(Event.MOUSEMOVE|Event.MOUSEUP);
						 }
						document.οnmοuseup=null;
						document.οnmοusemοve=null;	
						for(var i=0;i<oLi.length;i++){
						  oLi[i].className="";
						}
							if(oNear){
								
								 oNear.style.zIndex=zx++;
								startMove(obj,aPos[oNear.index]);
								startMove(oNear,aPos[obj.index]);
								var temp=oNear.index;
								oNear.index=obj.index;
								obj.index=temp;
								
								
							}else{
								
								
								startMove(obj,aPos[obj.index]);
								
							}  
							
						return false;	
		
					}

	}	
	
	
}
//找出相遇点中最近的元素
function  findObj(obj){
  var arr1=[];
  var arr2=[];
  var res=null;
   var minnum=9999999;
   var minLi=null;
  
	  for(var i=0;i<oLi.length;i++){
        	 res=isButt(obj,oLi[i]);	 
			 if(oLi[i]!=obj&&res){
				
				 arr1.push(dian(obj,oLi[i]));
				 arr2.push(oLi[i]); 
			 }  
		  
	  }
 
   for(var i=0;i<arr1.length;i++){
	  
	    if(arr1[i]<minnum){
		    minnum=arr1[i];
			minLi=arr2[i];	
		}

   }	  
	 return minLi; 
}

//求亮点之间的距离
function  dian(obj1,obj2){
	var a=(obj1.offsetLeft + obj1.offsetWidth / 2) - (obj2.offsetLeft + obj2.offsetWidth / 2);
	var b=(obj1.offsetTop + obj1.offsetHeight / 2) - (obj2.offsetTop + obj2.offsetHeight / 2);
	return Math.sqrt(a*a+b*b);
	
}


//碰撞检测
function  isButt(aObj,bObj){
	var a1=aObj.offsetLeft;
	var b1=aObj.offsetTop;
	var c1=aObj.offsetLeft+aObj.offsetWidth;
	var d1=aObj.offsetTop+aObj.offsetHeight;
	
	var a2=bObj.offsetLeft;
	var b2=bObj.offsetTop;
	var c2=bObj.offsetLeft+bObj.offsetWidth;
	var d2=bObj.offsetTop+bObj.offsetHeight;	
	if(a2>c1||b2>d1||a1>c2||b1>d2){
	  return false;	
		
	}else{
		
	  return true;	
	}

}
//获取最终样式
function getStyle(obj, attr)
{
	return parseFloat(obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, null)[attr])
}

//运动框架
function startMove(obj, pos, onEnd)
{
	clearInterval(obj.timer);
	obj.timer = setInterval(function ()
	{
		doMove(obj, pos, onEnd)
	}, 30)	
}
function doMove(obj, pos, onEnd)
{
	var iCurL = getStyle(obj, "left");
	var iCurT = getStyle(obj, "top");
	var iSpeedL = (pos.left - iCurL) / 5;
	var iSpeedT = (pos.top - iCurT) / 5;
	iSpeedL = iSpeedL > 0 ? Math.ceil(iSpeedL) : Math.floor(iSpeedL);
	iSpeedT = iSpeedT > 0 ? Math.ceil(iSpeedT) : Math.floor(iSpeedT);
	if (pos.left == iCurL && pos.top == iCurT)
	{
		clearInterval(obj.timer);
		onEnd && onEnd()
	}
	else
	{
		obj.style.left = iCurL + iSpeedL + "px";
		obj.style.top = iCurT + iSpeedT + "px";	
	}
}


</script>
</div>
</body>
</html>

 

转载于:https://www.cnblogs.com/chaoming/p/3164891.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值