JavaScript中的拖拽(以及Html5中的拖放)
JavaScript中的拖拽(以及Html5中的拖放)
原理:
html:
<div id="div1"></div>
css:
#div1{ height:120px; width:120px; background:green; position:absolute; }
javascript:
window.onload=function (){ var obj=document.getElementById("div1"); obj.onmousedown=function (ev){ //获取鼠标相对 div的距离 var e= ev || event; var relativeX=e.clientX-obj.offsetLeft; var relativeY=e.clientY-obj.offsetTop; //相对距离; //div太小,将事件加载document上; document.onmousemove=function (ev){ //重新计算div的位置滴呀 var e=ev || event; //这里我们还要限制物体运动的边界; var l=e.clientX-relativeX; //物体的位置,是以鼠标的位置来计算出来的 var t=e.clientY-relativeY; l<0?l=0:null; //左边界 l>document.documentElement.clientWidth-obj.offsetWidth?l=document.documentElement.clientWidth-obj.offsetWidth:null; //右边界 t>document.documentElement.clientHeight-obj.offsetHeight?t=document.documentElement.clientHeight-obj.offsetHeight:null;//下边界 t<0?t=0:null; //上边界 obj.style.left=l+'px'; obj.style.top=t+'px'; } //当鼠标松开时候,清空 document.onmouseup=function (){ document.onmousemove=null; document.onmouseup=null; } return false; //解决火狐中bug } }
上面的代码是在可视的区域中运动的滴呀;
如果body的高度和宽度超出我们浏览大小,显出出了滚动条;
那么就要改进坐标的获取方式了;
如下:
//得到鼠标的坐标滴哎呀 function getPosition(e){ var clientx=e.clientX; var clienty=e.clientY; var scrollLeft=document.body.scrollLeft || document.documentElement.scrollLeft; var scrollTop=document.body.scrollTop || document.documentElement.scrollTop; var x=clientx+scrollLeft; var y=clienty+scrollTop; return {x:x,y:y}; }
接下来,我们再来总结:
无法拖出可视区(上面的就是)
无法拖出整个页面(上面的就是)
无法拖出某个父级元素
原理:
html:
<div id="parent"> <div id="son"> </div> </div>
css:
#parent{ height:400px; width:400px; background:green; position:relative; opacity:0.5; filter:alpha(opacity:50); margin:0 auto; } #son{ height:80px; width:80px; background:red; opacity:0.5; filter:alpha(opacity:50); position:absolute; }
javascript:
//然后son在parent中移动,但不能超出边框; window.onload=function (){ var son=document.getElementById("son"); var parent=document.getElementById("parent"); son.onmousedown=function (ev){ var e=ev || event; //鼠标坐标,是相对整个页面的滴啊 //这里的offsetLeft 和 offsetTop 相对于parent的值滴呀 var relativeX=e.clientX-son.offsetLeft; var relativeY=e.clientY-son.offsetTop; //将事件绑定在我们的document上 document.onmousemove=function (ev){ var e=ev || event; //物体在浏览其中移动不用管,关键是限制他的边界; var x=e.clientX-relativeX; var y=e.clientY-relativeY; if(x<0){ x=0; }else if(x>(parent.offsetWidth-son.offsetWidth)){ //offsetWidth是他的盒子模型宽度 x=parent.offsetWidth-son.offsetWidth; } if(y<0){ y=0; }else if(y>(parent.offsetHeight-son.offsetHeight)){ y=parent.offsetHeight-son.offsetHeight; } son.style.left=x+'px'; son.style.top=y+'px'; } document.onmouseup=function(){ document.onmousemove=null; document.onmouseup=null; } } }
还有一个磁性吸附;
其实,所谓的磁性吸附,就就是当div快要到达边界的时候,马上让它到达边界,如;
if(x<10){
x=0;
}//就是这种效果滴呀
上面的代码就能达到所谓的“磁性吸附的效果滴呀”。
上面的拖拽都是托的空的div,那么如果,div中有文字,或者div周围有文字呢?
就会出现文本被选中的情况!
解决方法:在son.onmousedown=function (){
return false; //最后一步阻止默认的行为;
//能够解决chrom ff 中的bug;
//但是,没法解决ie9一下版本的兼容性问题
}
但是ie有个独特的事件捕获的概念;
我们就可以利用者一点来解决这个bug
document.onmouseup=function(){ document.onmousemove=null; document.onmouseup=null; if(son.setCapture!=undefined){ son.releaseCaputre(); } } if(son.setCapture!=undefined){ son.setCaputre(); } return false; } }
终结版:带框的拖拽
好吧,最后带来我们的额终结版的拖拽!(完整代码如下)
<!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"> #parent{ height:400px; width:400px; background:green; position:relative; opacity:0.5; filter:alpha(opacity:50); margin:0 auto; } #son{ height:80px; width:80px; background:red; opacity:0.5; filter:alpha(opacity:50); position:absolute; } .box{ position:absolute; border:1px dashed black; } </style> </head> <body> <div id="parent"> <div id="son"> 测试 测试 测试 测试 测试 </div> </div> </body> <script type="text/javascript"> //然后son在parent中移动,但不能超出边框; window.onload=function (){ var son=document.getElementById("son"); var parent=document.getElementById("parent"); son.onmousedown=function (ev){ var e=ev || event; //鼠标坐标,是相对整个页面的滴啊 //这里的offsetLeft 和 offsetTop 相对于parent的值滴呀 var relativeX=e.clientX-son.offsetLeft; var relativeY=e.clientY-son.offsetTop; //将事件绑定在我们的document上 //这里我们再创建一个div var ele_div=document.createElement('div'); ele_div.className='box';//初始样式 //初始高度宽度 --还要减去我们border ele_div.style.height=son.offsetHeight-2+'px'; ele_div.style.width=son.offsetWidth-2+'px'; //初始位置; ele_div.style.top=son.style.top; ele_div.style.left=son.style.left; //document.body.appendChild(ele_div); parent.appendChild(ele_div); document.onmousemove=function (ev){ var e=ev || event; //物体在浏览其中移动不用管,关键是限制他的边界; var x=e.clientX-relativeX; var y=e.clientY-relativeY; if(x<10){ x=0; }else if(x>(parent.offsetWidth-son.offsetWidth)){ //offsetWidth是他的盒子模型宽度 x=parent.offsetWidth-son.offsetWidth; } if(y<10){ y=0; }else if(y>(parent.offsetHeight-son.offsetHeight)){ y=parent.offsetHeight-son.offsetHeight; } //移动的仅仅是我们的虚框; ele_div.style.left=x+'px'; ele_div.style.top=y+'px'; } document.onmouseup=function(){ son.style.left=ele_div.style.left; son.style.top=ele_div.style.top; //并且移除该该元素 //document.body.removeChild(ele_div); parent.removeChild(ele_div); document.onmousemove=null; document.onmouseup=null; if(son.setCapture!=undefined){ son.releaseCaputre(); } } if(son.setCapture!=undefined){ son.setCaputre();//这样就算是解决了这个bug滴呀 } return false; } } </script> </html>
效果:
接下来是HTML5中的拖放到指定的位置滴呀;区分拖放的拖拽滴呀;