1、拖拽的原理:
主要是用了三个鼠标事件,onmousedown、onmousemove、onmouseup。当鼠标按下时,计算出鼠标距离拖拽物体border的距离,假设拖拽物体是一个100*100px的小块,在鼠标按下时再检测鼠标移动后鼠标的位置,用当前鼠标的位置去减去鼠标距离拖拽物体border的距离,把作差的结果赋给div的left和top,这样就达到拖拽的目的,当然当鼠标释放时,还是把onmousemove、onmousedown事件清除,已达到拖拽完鼠标释放的目的。这就是简单的拖拽原理。也是最实用的。
下面是源码:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <style> #div1{100px; height: 100px; background-color: red; position: absolute} </style> <script> window.onload=function(){ var oDiv=document.getElementById(id); oDiv.onmousedown=function(ev){ oEvent=ev||event; //鼠标距离小块border的距离 var disX=oEvent.clientX-oDiv.offsetLeft; var disY=oEvent.clientY-oDiv.offsetTop; document.onmousemove=function(ev){ oEvent=ev||event; //移动后,想要移动的距离 var l=oEvent.clientX-disX; var t=oEvent.clientY-disY; //把l和t赋值给div的left和top让其达到运动的效果 oDiv.style.left=l+'px'; oDiv.style.top=t+'px'; }; document.onmouseup=function(){ //鼠标释放后,把事件清空 document.onmousedown=null; document.onmousemove=null } } } </script> <body> <div id="div1"></div> </body> </html>
在这里不得不说下,style.width/height和offsetLeft/Top的区别,下面是以width举例的,height也类似
if(l<0) { l=0; } else if(l>document.documentElement.clientWidth-oDiv.offsetWidth) { l=document.documentElement.clientWidth-oDiv.offsetWidth; } if(t<){ t=0; } else if(t>document.documentElement.clientHeight-oDiv.offsetHeight){ t=document.documentElement.clientHeight-oDiv.offsetHeight }
document.documentElement.clientWidth就是当前网页窗口的宽度,如果调整了网页宽口的宽度,document.documentElement.clientWidth也会根据你调整后变化。
document.documentElement.clientHeight也类似
下面附一张图来解释原理
left和top容易理解,right和bottom是这样的,上图 a=offsetLeft b=document.documentElement.clientWidth c=小块宽度,当a>b-c时说明小块出去了,这时候把l=document.documentElement.clientWidth-oDiv.offsetWidth。height同理,这样就达到了不让小块出界的目的
3、磁性吸附
磁性吸附就是小块快到上下左右边界时,让小块立马贴近边界,达到吸附的目的
代码如下:
if(l<50) { l=0; } else if(l>document.documentElement.clientWidth-oDiv.offsetWidth-50) { l=document.documentElement.clientWidth-oDiv.offsetWidth; } if(t<50){ t=0; } else if(t>document.documentElement.clientHeight-oDiv.offsetHeight-50){ t=document.documentElement.clientHeight-oDiv.offsetHeight }
磁性吸附其实和限制小块范围的原理类似,当l还有50px小于0,这时候把l等于0,以至于在l<50范围内,都让l=0; 当l>document.documentElement.clientWidth-oDiv.offsetWidth-50时,l=document.documentElement.clientWidth-oDiv.offsetWidth让小块立即贴近页面右边框。
如上图,当小块向右距离小于50px 都是l>document.documentElement.clientWidth-oDiv.offsetWidth-50,把其l=document.documentElement.clientWidth-oDiv.offsetWidth,这样就达成了磁性吸附的目的。
4、碰撞检测
碰撞检测的原理很简单,有两个div,div1和div2,在div1可以移动 div2保持不动,div1在div2大小之外,就让其颜色不变,当在div2内,让其颜色改变。
代码如下:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <style> #div1{width:100px; height: 100px; background-color: red; position: absolute;z-index:2;} #div2{width:100px; height: 100px; background-color: green; position: absolute ;left:300px;top:500px;z-index: 1} </style> <script> window.onload=function(){ var oDiv=document.getElementById('div1'); var oDiv2=document.getElementById('div2'); oDiv.onmousedown=function(ev){ oEvent=ev||event; //移动前的距离window的距离 var disX=oEvent.clientX-oDiv.offsetLeft; var disY=oEvent.clientY-oDiv.offsetTop; document.onmousemove=function(ev){ oEvent=ev||event; //移动后,想要移动的距离 var l=oEvent.clientX-disX; var t=oEvent.clientY-disY; var a=oDiv.offsetLeft; var b=oDiv.offsetHeight+oDiv.offsetLeft; var c=oDiv.offsetTop; var d=oDiv.offsetHeight+oDiv.offsetTop; var a2=oDiv2.offsetLeft; var b2=oDiv2.offsetHeight+oDiv2.offsetLeft; var c2=oDiv2.offsetTop; var d2=oDiv2.offsetHeight+oDiv2.offsetTop; if(b<a2||d<c2||c>d2||a>b2){ oDiv2.style.background='green' } else{ oDiv2.style.background='yellow' } //把l和t赋值给div的left和top让其达到运动的效果 oDiv.style.left=l+'px'; oDiv.style.top=t+'px'; }; document.onmouseup=function(){ //鼠标释放后,把事件清空 document.onmousedown=null; document.onmousemove=null } } }; </script> <body> <div id="div1"></div> <div id="div2"></div> </body> </html>
这红圈之外,让其颜色不变,在红圈之内,让其颜色改变。
if(b<a2||d<c2||c>d2||a>b2){
oDiv2.style.background='green'
}
else{
oDiv2.style.background='yellow'
}


就是要达到上图的效果
代码如下:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <style> #div1{width:100px; height: 100px; background-color: yellow; position: absolute} .box{position: absolute;border: dotted 1px black} </style> <script> window.onload=function(){ var oDiv=document.getElementById('div1'); var newDiv=document.createElement('div'); oDiv.onmousedown=function(ev){ oEvent=ev||event; //移动前的距离window的距离 var disX=oEvent.clientX-oDiv.offsetLeft; var disY=oEvent.clientY-oDiv.offsetTop; document.onmousemove=function(ev){ oEvent=ev||event; //移动后,想要移动的距离 var l=oEvent.clientX-disX; var t=oEvent.clientY-disY; newDiv.className='box'; newDiv.style.width=oDiv.offsetWidth-2+'px'; newDiv.style.height=oDiv.offsetHeight-2+'px'; document.body.appendChild(newDiv); oDiv.style.opacity=0.5; //把l和t赋值给div的left和top让其达到运动的效果 newDiv.style.left=l+'px'; newDiv.style.top=t+'px'; }; document.onmouseup=function(){ //鼠标释放后,把事件清空 document.onmousedown=null; document.onmousemove=null; document.body.removeChild(newDiv); oDiv.style.left=newDiv.style.left; oDiv.style.top=newDiv.style.top; oDiv.style.opacity=1; } } } </script> <body> <div id="div1" ></div> </body> </html>
原理就是:当鼠标按下时,创建一个div,当鼠标抬起时,删除新创建的div,注意的一点就是:这时候移动的不是实际小块的位置,而是新建div的位置,让新建div移到某一位置后,再把新建div的left和top赋给小块的left和top,这样就达到边框先移动,移到某一位置后,真实的物体再到这一位置。
6、利用div改变其父级的大小,就像实现博客园写随笔的的框大小的调整
代码如下:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <style> #div1{width:10px; height: 10px;bottom: 0; right: 0; background-color: red; position: absolute} #div2{width:100px; height: 100px; background-color: green; position: relative} </style> <script> window.onload=function(){ var oDiv=document.getElementById('div1'); var oDiv2=document.getElementById('div2'); oDiv.onmousedown=function(ev){ oEvent=ev||event; //移动前的距离window的距离 var disX=oEvent.clientX-oDiv.offsetLeft; var disY=oEvent.clientY-oDiv.offsetTop; document.onmousemove=function(ev){ oEvent=ev||event; //移动后,想要移动的距离 var l=oEvent.clientX-disX+oDiv.offsetWidth; var t=oEvent.clientY-disY+oDiv.offsetHeight; //把l和t赋值给div的left和top让其达到运动的效果 oDiv2.style.width=l+'px'; oDiv2.style.height=t+'px'; }; document.onmouseup=function(){ //鼠标释放后,把事件清空 document.onmousedown=null; document.onmousemove=null } } } </script> <body> <div id="div2"><div id="div1"></div></div> </body> </html>
原理:和基本拖拽的唯一区别就是两点,一、父级 position是relative 子集position是absolute,这样保证子集的父级内,bottom:0和right:0让子集在右下角
二、这时候拖拽改变了不是原物体的位置,而是把拖拽到某一位置的坐标,赋给父级div的宽度,注意:是style.width,它是一个字符串 带'px',height类似,这样就形成了一个改变父级边框大小的效果。
总结:
拖拽是常见的一种交互效果,掌握拖拽也对我们熟悉页面结构有很大帮助,下面附一张我珍藏好久的牛x图,了解各种宽高之间的区别