经常在各大网站看到一些模块可以让用户自由拖拽,把网页的可操作性交给了用户。比如百度的登陆层,是可以实现拖拽的…那么这种拖拽是如何实现的呢?

现在,我们把拖拽特效的分解成几个动作。分别是鼠标按下,鼠标拖动过程,鼠标释放三个步骤,以下是它们的分部介绍:

onmousedown 鼠标按下

鼠标按下时(当然鼠标按着的时候也包括鼠标拖着div块在移动,还有就是在div上松开鼠标。),我们需要记录光标和div的距离。假设拖动的div是obj。则代码可以整理为:

obj.onmousedown=function(ev){
var e=event||ev,
disX=e.clientX-obj.offsetLeft,
disY=e.clientY-obj.offsetTop;

}

onmousemove 鼠标拖动过程中…

拖拽的过程中,光标和div的距离是保持不变的,这样才能产生拖拽的效果。

obj.onmousedown=function(ev){
var e=event||ev,
disX=e.clientX-obj.offsetLeft,
disY=e.clientY-obj.offsetTop;
obj.onmousemove=function(ev){
var e=ev||event;
obj.style.left=e.clientX-disX+"px"; //重新定位obj的位置
obj.style.top=e.clientY-disY+"px";
}

}

onmouseup 鼠标释放

当拖拽完成时,我们需要把onmousemove和onmouseup清空。

obj.onmousedown=function(ev){
var e=event||ev,
disX=e.clientX-obj.offsetLeft,
disY=e.clientY-obj.offsetTop;
obj.onmousemove=function(ev){
var e=ev||event;
obj.style.left=e.clientX-disX+"px";//重新定位obj的位置
obj.style.top=e.clientY-disY+"px";
}
obj.onmouseup=function(){
obj.onmousemove=null;
obj.onmouseup=null;
}

}

完整代码如下:

(function(obj){
obj.onmousedown=function(ev){
var e=ev||event,disX=e.clientX-obj.offsetLeft,disY=e.clientY-obj.offsetTop;
if(obj.setCapture){
obj.onmousemove=fnMove;
obj.onmouseup=fnUp;
obj.setCapture();
}
else{
document.onmousemove=fnMove;
document.onmouseup=fnUp;
}
function fnMove(ev){
var e=ev||event;
obj.style.left=e.clientX-disX+"px";
obj.style.top=e.clientY-disY+"px";
}
function fnUp(){
this.onmousemove=null;
this.onmouseup=null;
if(obj.setCapture){
obj.releaseCapture();
}
}
return false;
}
})(obj);

因为ie下存在捕获,即当拖动obj时,如果网页中还存在其他内容,则会造成其他内容被选中,而且obj拖动时不够流畅。所以这里,需要进行判断,并且在拖拽完成后需要释放捕获:

if(obj.setCapture){  
obj.onmousemove=fnMove;
obj.onmouseup=fnUp;
obj.setCapture();
}

if(obj.setCapture){
obj.releaseCapture();
}

另外,由于在火狐浏览器也存在默认的bug。所以最后还要加上 return false;