转载地址: http://www.wxwdesign.com/archives/javascript_drag_drop
为了提高用户体验,让操作更便捷化,拖拽操作会很常见,比如操作系统里面,你要删除一个文件,你可以直接把它拖入回收站,wordpress也有类型的功能,你想在侧边栏增加一个板块,可以直接拖一个小工具过去就行了,这的确方便了很多。如何在网页里面实现拖拽,本文做一个简单的解析。
首先说一下拖拽的原理:
鼠标在目标上按下(mousedown)——>摁住鼠标不放,然后移动鼠标(mousemove)——>获取鼠标的坐标位置,让目标跟随鼠标——>鼠标释放(mouseup),让目标停止跟随。
(示意图)
基本原理就是这样的,具体一些扩展应用,比如把一个对象拖放到另一个容器里,只需要做进一步的判断就可以了。
获取鼠标位置(坐标)
在拖拽开始之前,我们需要先知道怎么得到鼠标的位置,不然拖拽就无法进行下去。
主要代码:
function getMousePos(e){
var e=window.event||e;
if(e.pageX||e.pageY){
return {x:e.pageX,y:e.pageY};
}
return{
x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
y:e.clientY + document.body.scrollTop-document.body.clientTop
};
}
简单的鼠标跟随效果
已经得到了鼠标的位置,下面可以设置一个对象,让它跟随鼠标移动,模仿拖拽的效果:
主要代码:
//创建drag对象
var drag=function(){
this.position=document.getElementById('position');
this.star=document.getElementById('follow');
this.pos=null;
this.follow=false;
this.a=document.getElementsByTagName('a');
}
//获取坐标
drag.prototype.getMousePos=function(e){
var e=window.event||e;
if(e.pageX||e.pageY){
return {x:e.pageX,y:e.pageY};
}
return{
x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
y:e.clientY + document.body.scrollTop-document.body.clientTop
};
}
//显示鼠标坐标值
drag.prototype.show=function(e){
this.pos=this.getMousePos(e);
this.position.innerHTML='x='+this.pos.x+', y='+this.pos.y;
if(this.follow){this.star.style.cssText='left:'+(this.pos.x+10)+'px;top:'+this.pos.y+'px';}
}
//初始化
drag.prototype.init=function(){
var that=this;
document.οnmοusemοve=function(e){that.show(e);}
this.a[0].οnclick=function(){that.follow=!that.follow;if(that.follow){this.innerHTML='停止跟随';}else{this.innerHTML='开始跟随';}}
this.a[0].οnfοcus=function(){this.blur();}
}
var drag_demo=new drag();
drag_demo.init();
HTML代码:
<a href="javascript:void(0)">开始跟随</a>
<div id="position"> </div>
<div id="follow">ⓐ✿</div>
简单拖拽的实现
有了上面的基础,我们就可以实现拖拽效果,其实就是给目标对象绑定onmousedown事件,然后让它跟随鼠标移动,当document的onmouseup发生的时候,停止跟随鼠标。为什么要用document的onmouseup,自己可以在实践中测试一下,鼠标可能会跑到目标对象的外面去,设定document的onmouseup能够避免这种现象造成的不良后果。
主要代码:
//创建drag对象
var drag=function(){
this.position=document.getElementById('position');
this.star=document.getElementById('follow');
this.pos=null;
this.follow=false;
}
//获取坐标
drag.prototype.getMousePos=function(e){
var e=window.event||e;
if(e.pageX||e.pageY){
return {x:e.pageX,y:e.pageY};
}
return{
x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
y:e.clientY + document.body.scrollTop-document.body.clientTop
};
}
//显示鼠标坐标值
drag.prototype.show=function(e){
this.pos=this.getMousePos(e);
if(this.follow){this.star.style.cssText='left:'+(this.pos.x-30)+'px;top:'+(this.pos.y-30)+'px';}
}
//初始化
drag.prototype.init=function(){
var that=this;
document.οnmοusemοve=function(e){that.show(e);}
this.star.οnmοusedοwn=function(){that.follow=true;}
document.οnmοuseup=function(){that.follow=false;}
}
var drag_demo=new drag();
drag_demo.init();
完善一点的案例
上面的拖拽似乎还很原始,需要进一步的改进,稍做改动,增加了一些拖动的限制,主要代码如下:
//创建drag对象
var drag=function(){
this.position=document.getElementById('position');
this.star=document.getElementById('follow');
this.areaBox=document.getElementById('area');
this.a=document.getElementsByTagName('a');
this.pos=null;
this.follow=false;
this.diffX=0;
this.diffY=0;
this.stopX=false;
this.stopY=false;
this.styleTemp='';
this.area={xstart:100,xend:300,ystart:100,yend:300};
this.setArea=false;
}
//获取坐标
drag.prototype.getMousePos=function(e){
var e=window.event||e;
if(e.pageX||e.pageY){
return {x:e.pageX,y:e.pageY};
}
return{
x:e.clientX + document.body.scrollLeft-document.body.clientLeft,
y:e.clientY + document.body.scrollTop-document.body.clientTop
};
}
//显示鼠标坐标值
drag.prototype.show=function(e){
this.pos=this.getMousePos(e);
if(this.follow){
if(this.setArea){
if((this.pos.x-this.diffX)<this.area.xstart){this.diffX=this.pos.x-this.area.xstart;}
if((this.pos.x-this.diffX)>this.area.xend){this.diffX=this.pos.x-this.area.xend;}
if((this.pos.y-this.diffY)<this.area.ystart){this.diffY=this.pos.y-this.area.ystart;}
if((this.pos.y-this.diffY)>this.area.yend){this.diffY=this.pos.y-this.area.yend;}
if(this.pos.x<this.area.xstart||this.pos.x>(this.area.xend+this.star.offsetWidth)||this.pos.y<this.area.ystart||(this.area.yend+this.star.offsetHeight)<this.pos.y){this.follow=false;}
}
this.styleTemp='';
if(!this.stopX){this.styleTemp+='left:'+(this.pos.x-this.diffX)+'px;';}else{this.styleTemp+='left:'+(this.star.offsetLeft)+'px;';}
if(!this.stopY){this.styleTemp+='top:'+(this.pos.y-this.diffY)+'px;';}else{this.styleTemp+='top:'+(this.star.offsetTop)+'px;';}
this.star.style.cssText=this.styleTemp;
}
}
//初始化
drag.prototype.init=function(){
var that=this;
document.οnmοusemοve=function(e){that.show(e);}
this.star.οnmοusedοwn=function(e){
that.follow=true;
that.pos=that.getMousePos(e);
that.diffX=that.pos.x-this.offsetLeft;
that.diffY=that.pos.y-this.offsetTop;
}
document.οnmοuseup=function(){that.follow=false;}
this.a[0].οnclick=function(){that.stopX=!that.stopX;that.stopY=false;}
this.a[1].οnclick=function(){that.stopY=!that.stopY;that.stopX=false;}
this.a[2].οnclick=function(){
that.setArea=!that.setArea;
if(that.setArea){
that.star.style.cssText='left:100px;top:100px;';
that.areaBox.style.display='block';
}else{
that.areaBox.style.display='none';
}
}
this.a[3].οnclick=function(){that.stopX=false;that.stopY=false;that.setArea=false;that.areaBox.style.display='none';}
}
var drag_demo=new drag();
drag_demo.init();
拖拽应用实例
利用拖拽调节图片透明度,查看示例
另外,如果有兴趣,你还可以参考这篇文章