JS拖拽效果
<!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"> html,body,div,ul,li,h1,h2,h3,h4,h5,h6,p,span{ margin:0; padding:0;-moz-user-select:none; } body{ overflow:hidden;} ul,li{ list-style:none;} li{ float:left;} #appCenter{ width:750px; margin:30px auto;} #appCenter .appDiv{ margin-bottom:15px;_zoom:1;} #appCenter .appDiv h3{ padding:5px; border-bottom:1px #ccc dotted;} #appCenter ul{ overflow:hidden; margin-left:30px;} #appCenter ul li{ width:80px; height:80px; position:relative; margin-right:20px; margin-top:20px; border:1px #fff dashed; display:inline;} #appCenter ul li div{ height:68px; background-position:center center; background-repeat:no-repeat; cursor:move;} #appCenter ul li p{ height:12px; line-height:12px; font-size:12px; text-align:center; } #appCenter ul li span{ display:block; width:19px; height:19px; position:absolute; right:0; top:-2px; cursor:pointer;} .plus{ background:url(http://d.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=90c53662fd039245a5b5e207b7afd5ff/6a63f6246b600c33d44f1e671b4c510fd9f9a16f.jpg)} .minus{ background:url(http://e.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=c114b4ab960a304e5622a3f2e1f3d6bb/a1ec08fa513d269765e5c8f254fbb2fb4316d86f.jpg)} .js-newLi{ position:absolute; opacity:0.5; filter:alpha(opacity=50); width:80px; height:80px;} .js-newLi div{ height:68px; background-position:center center; background-repeat:no-repeat; cursor:move;} .js-newLi p{ height:12px; line-height:12px; font-size:12px; text-align:center; } .js-newLi span{ display:block; width:19px; height:19px; position:absolute; right:0; top:-2px; cursor:pointer;} #appCenter ul li.js-liBorderStyle{ border:1px #ccc dashed;} </style> <script type="text/javascript"> //取元素 var $=function(element){ return typeof element=="string"?document.getElementById(element):element; },_$=function(oParent,nodeName){ return oParent.getElementsByTagName(nodeName); }; //模拟报文数据 var aMyApp=[{name:'应用1',src:'http://e.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=d7deff4e63d9f2d3241127e799d7fb2e/ca1349540923dd54fa6467c7d009b3de9c82480e.jpg'}, {name:'应用2',src:'http://d.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=bb9f24dcac4bd11300cdb43a6a94d532/b17eca8065380cd7e2296242a044ad345982816e.jpg'}, {name:'应用3',src:'http://b.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=33e12cacc995d143de76e72b43cbf33f/b3119313b07eca80147ef948902397dda1448322.jpg'}, {name:'应用4',src:'http://b.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=a8544684b151f819f5250042ea8f3bd0/9a504fc2d5628535749b128e91ef76c6a7ef6322.jpg'}, {name:'应用5',src:'http://g.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=a03c2f2b4bed2e73f8e98524b73ad0b6/e61190ef76c6a7ef585d6889fcfaaf51f3de6622.jpg'}, {name:'应用6',src:'http://e.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=62ed5270cf1b9d168ec79969c3e5c5b2/a8773912b31bb051ec327387377adab44aede00f.jpg'}, {name:'应用7',src:'http://c.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=a03df7977af40ad111e4c4eb671760e2/5fdf8db1cb134954a36528cb574e9258d1094a22.jpg'}, {name:'应用8',src:'http://b.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=9432f948902397ddd2799b0c69b9c38a/7a899e510fb30f24b3ad2cacc995d143ad4b036e.jpg'}, {name:'应用9',src:'http://b.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=29a8f96b30adcbef05347d0e9c945fe0/ac4bd11373f08202a3a551904afbfbedab641b6e.jpg'}]; var aOtherApp=[{name:'应用10',src:'http://b.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=f4acc34cd439b60049ce0cbfd96b4417/0ff41bd5ad6eddc4b0b8745438dbb6fd536633c6.jpg'}, {name:'应用11',src:'http://a.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=e76ae440a8ec8a13101a54e8c738e0b2/574e9258d109b3de2cc424c7cdbf6c81800a4c22.jpg'}, {name:'应用12',src:'http://h.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=0dbdb6896c224f4a5399701b39cce16f/a9d3fd1f4134970a8f08d08094cad1c8a7865d22.jpg'}, {name:'应用13',src:'http://h.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=5f6487910df3d7ca08f63c7ec224cf34/a686c9177f3e67090e7b85503ac79f3df8dc5522.jpg'}, {name:'应用14',src:'http://h.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=da6970aae4dde711e3d240fe97d4bf26/8b82b9014a90f6037c865ce83812b31bb051ed6f.jpg'}, {name:'应用15',src:'http://b.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=5da0c34e2e2eb938e86d79fae559f408/eac4b74543a98226c6bbeb888b82b9014a90eb23.jpg'}, {name:'应用16',src:'http://g.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=ee58cfb62cf5e0feea188a096c5b4595/8ad4b31c8701a18b9991d2e09f2f07082838fe23.jpg'}, {name:'应用17',src:'http://g.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=831a87144610b912bbc1f5f6f3c68d3e/d6ca7bcb0a46f21ff0029efcf7246b600c33ae6f.jpg'}, {name:'应用18',src:'http://d.hiphotos.bdimg.com/album/s%3D680%3Bq%3D90/sign=838c8359a6efce1bee2bcbc29f6a82e3/728da9773912b31ba3320d868718367adbb4e1c7.jpg'}]; window.onload=function(){ new AppCenter('appCenter','myApp','otherApp',{ myAppList:aMyApp, otherAppList:aOtherApp }); } //应用中心类 function AppCenter(){ this.init.apply(this,arguments); } //应用中心原型 AppCenter.prototype={ //鼠标按下时的x坐标 _downX:0, //鼠标按下时的y坐标 _downY:0, //鼠标移动时的x坐标 _moveX:0, //鼠标移动时的y坐标 _moveY:0, //移动图标的下标 _index:0, //初始化方法 // oMainDivId-主div的id sMyAppId-我的应用UL的id sOtherAppId-其他应用UL的id //confing{object}-配置参数{myAppList:'我的应用数据{Array}',otherAppList:'其他应用数据{Array}'} init:function(sMainDivId,sMyAppId,sOtherAppId,confing){ this.oMainDiv=$(sMainDivId); this.oMyApp=$(sMyAppId); this.oOtherApp=$(sOtherAppId); this.aMyAppList=confing.myAppList; this.aOtherAppList=confing.otherAppList; this._createAppCenter(this.oMyApp,this.aMyAppList,0); this._createAppCenter(this.oOtherApp,this.aOtherAppList,1); this._OnApp(this.oMainDiv); this._addDeleteApp(this.oMyApp,this.oOtherApp); this._addDeleteApp(this.oOtherApp,this.oMyApp); this._moveApp(this.oMyApp,this.oOtherApp); this._moveApp(this.oOtherApp,this.oMyApp); }, //创建应用中心内容 _createAppCenter:function(oElement,aAppList,flag){ var sLiContent='',len=aAppList.length,sBtnClass=''; var aAppDivList=_$(oElement,'div'),aAppPList=_$(oElement,'p'); sBtnClass=flag==0?'minus':'plus'; for(var i=0;i<len;i++){ sLiContent+='<li><div></div><p></p><span class="'+sBtnClass+'"></span></li>'; } oElement.innerHTML=sLiContent; for(var j=0;j<len;j++){ var div=aAppDivList[j],p=aAppPList[j],params=aAppList[j]; div.style.backgroundImage="url("+params.src+")"; p.innerHTML=params.name; } }, //鼠标移入移出图标 _OnApp:function(oMainDiv){ var _this=this; oMainDiv.onmouseover=function(event){ var e=event||window.event,t=e.target||e.srcElement; if(t.nodeName.toLowerCase()=='li'){ _this.addClass(t,'js-liBorderStyle'); }else if(t.parentNode.nodeName.toLowerCase()=='li'){ _this.addClass(t.parentNode,'js-liBorderStyle'); } } oMainDiv.onmouseout=function(event){ var e=event||window.event,t=e.target||e.srcElement; if(t.nodeName.toLowerCase()=='li'){ _this.removeClass(t,'js-liBorderStyle'); }else if(t.parentNode.nodeName.toLowerCase()=='li'){ _this.removeClass(t.parentNode,'js-liBorderStyle'); } } }, //拖动图标改变位置 _moveApp:function(oDragUl,oOtherUl){ var _this=this; oDragUl.onmousedown=function(event){ var e=event||window.event,t=e.target||e.srcElement; //class不是js-liBorderStyle的li元素集合 _this._aLiList=[]; if(t.nodeName.toLowerCase()=='div'&&t.className!='appDiv'){ var oLi=t.parentNode,oCopyLi=oLi.cloneNode(true),oNewLi1=document.createElement('li'),oSpan=_$(oCopyLi,'span')[0]; document.body.appendChild(oCopyLi); _this.addClass(oCopyLi,'js-newLi'); oSpan.style.display="none"; oCopyLi.style.left=_this.offset(oLi).left+"px"; oCopyLi.style.top=_this.offset(oLi).top+"px"; oLi.parentNode.replaceChild(oNewLi1,oLi); _this.addClass(oNewLi1,'js-liBorderStyle'); _this._downX=e.clientX; _this._downY=e.clientY; _this._offsetLeft=oCopyLi.offsetLeft; _this._offsetTop=oCopyLi.offsetTop; _this.aLiList=_$(_this.oMainDiv,'li'); //_this._aLiList集合 for(var i=0,len=_this.aLiList.length;i<len;i++){ var li=_this.aLiList[i]; if(li.className!='js-liBorderStyle'){ _this._aLiList.push(li); } } //鼠标按下时移动图标的位置 _this._getAppLocation(_this._offsetLeft+80,_this._offsetTop+80); document.onmousemove=function(event){ var e=event||window.event,t=e.target||e.srcElement; var _X=e.clientX,_Y=e.clientY,_mLeft=_this._offsetLeft+_X-_this._downX,_mtop=_this._offsetTop+_Y-_this._downY; var oSize=_this._overBorder(_mLeft,_mtop); _mLeft=oSize.left?oSize.left:_mLeft; _mtop=oSize.top?oSize.top:_mtop; oCopyLi.style.left=_mLeft+"px"; oCopyLi.style.top=_mtop+"px"; var index=_this._getAppLocation(_mLeft,_mtop); _this._insertApp(_Y,_this._aLiList[index],oNewLi1,_this.oMyApp); _this._insertApp(_Y,_this._aLiList[index],oNewLi1,_this.oOtherApp); } document.onmouseup=function(event){ var e=event||window.event,t=e.target||e.srcElement,left,top,oSpan2; left=_this.offset(oNewLi1).left; top=_this.offset(oNewLi1).top; _this.animate(oCopyLi,{left:left,top:top},100,function(){ document.body.removeChild(oCopyLi); oNewLi1.innerHTML=oCopyLi.innerHTML; oSpan2=_$(oNewLi1,'span')[0]; oSpan2.style.display="block"; _this.removeClass(oNewLi1,'js-liBorderStyle'); var oLiSpan=_$(oNewLi1,'span')[0]; var oPBtn=oNewLi1.parentNode; oPBtn==_this.oMyApp?oLiSpan.className="minus":oLiSpan.className="plus"; }); document.onmousemove=null; document.onmouseup=null; } } } }, //点击加减号增删图标 oDragUl-点击的加减号所在的UL元素 oAnotherUl-另一个UL元素 _addDeleteApp:function(oDragUl,oAnotherUl){ var aDelList=_$(oDragUl,'li'),oAddList=_$(oAnotherUl,'li'),_this=this; oDragUl.onclick=function(event){ var e=event||window.event,t=e.target||e.srcElement; if(t.nodeName.toLowerCase()=='span'){ var sBtnClass=t.className,pNode=t.parentNode,oCopyLi=oCopyLi2=pNode.cloneNode(true); var oNewLi1=document.createElement('li'),oNewLi2=document.createElement('li'); document.body.appendChild(oCopyLi); _this.addClass(oCopyLi,'js-newLi'); oCopyLi.style.left=_this.offset(pNode).left+"px"; oCopyLi.style.top=_this.offset(pNode).top+"px"; oDragUl.replaceChild(oNewLi1,pNode); oAnotherUl.appendChild(oNewLi2); _this.addClass(oNewLi1,'js-liBorderStyle'); _this.addClass(oNewLi2,'js-liBorderStyle'); _this.animate(oCopyLi,{left:_this.offset(oNewLi2).left,top:_this.offset(oNewLi2).top},150,function(){ oNewLi1.parentNode.removeChild(oNewLi1); document.body.removeChild(oCopyLi); oNewLi2.innerHTML=oCopyLi2.innerHTML; _this.removeClass(oNewLi2,'js-liBorderStyle'); var oLiSpan=_$(oNewLi2,'span')[0]; sBtnClass=='plus'?oLiSpan.className="minus":oLiSpan.className="plus"; }); } } }, //图标超出边界处理 _overBorder:function(left,top){ var x=0,y=0,oMainDiv=this.oMainDiv,oSize={}; if(left<oMainDiv.offsetLeft){ x=oMainDiv.offsetLeft; } if(left>oMainDiv.offsetLeft+oMainDiv.offsetWidth){ x=oMainDiv.offsetLeft+oMainDiv.offsetWidth; } if(top<oMainDiv.offsetTop){ y=oMainDiv.offsetTop; } if(top>oMainDiv.offsetTop+oMainDiv.offsetHeight){ y=oMainDiv.offsetTop+oMainDiv.offsetHeight; } oSize.left=x; oSize.top=y; return oSize; }, //边框随鼠标移动改变位置 _insertApp:function(y,oOldElement,oNewElement,oParent){ var aLiList=_$(oParent,'li'),oLastLi=aLiList[aLiList.length-1]; if(y>this.offset(oParent).top&&y<this.offset(oParent).top+oParent.offsetHeight){ try{ oParent.insertBefore(oNewElement,oOldElement); }catch(error){ oParent.appendChild(oNewElement); } } }, //计算移动图标所处的位置 _getAppLocation:function(x,y){ var liList=this.aLiList,liW=liList[0].offsetWidth; for(var i=0,len=liList.length;i<len;i++){ var li=liList[i],left=this.offset(li).left,top=this.offset(li).top; if((x>left-liW+40&&x<left+liW-40)&&y>top-liW+20&&y<top+liW-20){ this._index=i; break; } } return this._index; }, //添加class addClass:function(node,_className){ if(!node.className){ node.className=_className; }else{ node.className+=" "+_className; } }, //删除class removeClass:function(node,_className){ var string=node.className; if(string.indexOf(_className)>0){ node.className=string.replace(' '+ _className,''); }else if(string.indexOf(_className)==0){ if(string.indexOf(' ')<0){ node.className=string.replace(_className,''); }else{ node.className=string.replace(_className+' ',''); } }else{ return; } }, //动画方法 obj-动画元素 params{object}-参数{left:'',top:''} time-时间 handler-回调函数 animate:function(obj,params,time,handler){ var node=$(obj),handlerFlag=true,_style=node.currentStyle?node.currentStyle:window.getComputedStyle(node,null); time=document.all?time*0.6:time*0.9; for(var p in params){ (function(n){ n=p; if(n=="left"||n=="top"){ var _old=parseInt(_style[n]),_new=parseInt(params[n]),_length=0,_tt=10; if(!isNaN(_old)){ var count=_old,length=_old<=_new?(_new-_old):(_old-_new),speed=length/time*_tt,flag=0; var anim=setInterval(function(){ node.style[n]=count+"px"; count=_old<=_new?count+speed:count-speed; flag+=_tt; if(flag>=time){ node.style[n]=_new+"px"; clearInterval(anim); } },_tt); } } })(p); } var timeHandler=setTimeout(function(){ if(handler&&typeof handler=="function"){ handler(); clearTimeout(timeHandler); } },time+100); }, //元素在文档中的位置 offset:function(obj){ var _offset={},node=$(obj); var left=node.offsetLeft,top=node.offsetTop; var parent = node.offsetParent; while(parent!=null){ left += parent.offsetLeft; top += parent.offsetTop; parent = parent.offsetParent; } _offset.left=left; _offset.top=top; return _offset; }, //获取元素样式 getStyle:function(obj,_style){ var node=$(obj); return node.currentStyle?node.currentStyle[_style]:window.getComputedStyle(node,null)[_style]; } } </script> </head> <body onselectstart="return false"> <div id="appCenter"> <div class="appDiv"> <h3>我的应用</h3> <ul id="myApp"></ul> </div> <div class="appDiv"> <h3>其他应用</h3> <ul id="otherApp"></ul> </div> </div> </body> </html>