《JavaScript学习笔记》:拖拽
拖拽在我们的生活中比较常见,原理也不难,如下:
假设有一个框,我们想要这个框有拖拽行为,拖拽行为就是跟着我们的鼠标移动而移动,而获取鼠标的位置的方法为:
var x = oEvent.clientX;
var y = oEvent.clientY;
当我们鼠标点击(鼠标点击对应onmousedown事件)时,我们记录鼠标此时的位置与框的距离(即图示中所表明的disX,disY),而disX是有鼠标所在的位置的横坐标和框的left决定,而disY是由鼠标所在的位置的纵坐标和框的top决定,因此,如下
var disX = oEvent.clientX-oDiv.offsetLeft;
var disY = oEvent.clientY-oDiv.offsetTop;
在我们移动鼠标的过程中,我们只需要保持框的left和top与鼠标的距离始终保存在disX、disY的距离即可。
下面我们就来看看拖拽的具体实现:
<font color='red' size=4>1、下面是拖拽的第一个版本</font>
<!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=gb2312" />
<title>无标题文档</title>
<style>
#div1 {width:200px;height:200px;background:red;display:block;position:absolute;}
</style>
<script>
window.onload=function()
{
var oDiv = document.getElementById('div1');
oDiv.onmousedown=function(ev)
{
var oEvent = ev||event;
var disX = oEvent.clientX - oDiv.offsetLeft;
var disY = oEvent.clientY - oDiv.offsetTop;
oDiv.onmousemove=function(ev)
{
var oEvent = ev||event;
var l=oEvent.clientX - disX;
var t=oEvent.clientY - disY;
oDiv.style.left=l+'px';
oDiv.style.top=t+'px';
};
oDiv.onmouseup=function()
{
oDiv.onmousemove=null;
oDiv.onmouseup=null;
};
return false;
};
};
</script>
</head>
<body>
<div id="div1">
</div>
</body>
</html>
这个版本中有三个事件,分别是在div中的onmousedown、onmouseomve、onmouseup.即鼠标按键、鼠标移动、鼠标按键抬起。
这个版本有一点bug:这个版本只能满足缓慢的拖拽,当我们的鼠标移动的速度比较快时,鼠标就会移动出去,而框体就不能跟着我们鼠标移动了。
为解决这个问题,我们只需要将onmousemove和onmouseup这个事件绑定在document上就可以解决。具体看第二个版本的代码
2、第二个版本
代码如下:
<!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=gb2312" />
<title>无标题文档</title>
<style>
#div1 {width:200px;height:200px;background:red;display:block;position:absolute;}
</style>
<script>
window.onload=function()
{
var oDiv = document.getElementById('div1');
oDiv.onmousedown=function(ev)
{
var oEvent = ev||event;
var disX = oEvent.clientX - oDiv.offsetLeft;
var disY = oEvent.clientY - oDiv.offsetTop;
document.onmousemove=function(ev)
{
var oEvent = ev||event;
var l=oEvent.clientX - disX;
var t=oEvent.clientY - disY;
oDiv.style.left=l+'px';
oDiv.style.top=t+'px';
};
document.onmouseup=function()
{
document.onmousemove=null;
document.onmouseup=null;
};
return false;
};
};
</script>
</head>
<body>
<div id="div1">
</div>
</body>
</html>
3、第三个版本
拖拽,拖拽,我们拖拽的范围只允许在其界面中,而不允许被拖拽到界面之外,因此我们需要在第二个版本上加上一些限制条件。
例如,宽度的限制条件如下:
0<=oDiv.style.left<=document.documentElement.clientWidth-oDiv.offsetWidth;
高度限制条件也类似
0<=oDiv.style.top<=document.documentElement.clientHeight-oDiv.offsetHeight;
完整代码代码如下:
<!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=gb2312" />
<title>无标题文档</title>
<style>
#div1 {width:200px;height:200px;background:red;display:block;position:absolute;}
</style>
<script>
window.onload=function()
{
var oDiv = document.getElementById('div1');
oDiv.onmousedown=function(ev)
{
var oEvent = ev||event;
var disX = oEvent.clientX - oDiv.offsetLeft;
var disY = oEvent.clientY - oDiv.offsetTop;
document.onmousemove=function(ev)
{
var oEvent = ev||event;
var l=oEvent.clientX - disX;
var t=oEvent.clientY - disY;
/*
以下的一些判断处理时防止拖拽被拖出界面之外
*/
if(l<0)//限制不能移出界面的左边
{
l=0;
}
else if(l>document.documentElement.clientWidth-oDiv.offsetWidth)//限制不能移出界面的右边
{
l=document.documentElement.clientWidth-oDiv.offsetWidth;
}
oDiv.style.left=l+'px';
if(t<0)//限制不能移出界面的上边
{
t=0;
}
else if(t>document.documentElement.clientHeight-oDiv.offsetHeight)//限制不能移出界面的下边
{
t=document.documentElement.clientHeight-oDiv.offsetHeight;
}
oDiv.style.top=t+'px';
};
document.onmouseup=function()
{
document.onmousemove=null;
document.onmouseup=null;
};
return false;
};
};
</script>
</head>
<body>
<div id="div1">
</div>
</body>
</html>
以上基本上就是简单的一个面向过程的拖拽实现。
继承和拖拽
上面从第二个版本的拖拽到第三个版本的拖拽,只是多了一些限制条件,对于这个我们可以用面向对象的继承来尝试的解决这个问题。
首先,我们将第二个版本的拖拽改为面向对象的程序。将面向过程的程序更改为面向对象的程序的方法见博文《第一个面向对象的程序》。
更改后的代码如下:
// JavaScript Document
function Drag(id)
{
_this=this;
this.oDiv = document.getElementById(id);
this.disX=0;
this.disY=0;
this.oDiv.onmousedown=function(ev)
{
_this.fnDown(ev);
};
};
Drag.prototype.fnDown=function (ev)
{
_this=this;
var oEvent = ev||event;
this.disX = oEvent.clientX - this.oDiv.offsetLeft;
this.disY = oEvent.clientY - this.oDiv.offsetTop;
document.onmousemove=function(ev)
{
_this.fnMove(ev);
};
document.onmouseup=function(ev)
{
_this.fnUp(ev);
};
};
Drag.prototype.fnMove=function (ev)
{
var oEvent = ev||event;
var l=oEvent.clientX - this.disX;
var t=oEvent.clientY - this.disY;
this.oDiv.style.left=l+'px';
this.oDiv.style.top=t+'px';
};
Drag.prototype.fnUp=function ()
{
document.onmousemove=null;
document.onmouseup=null;
};
再利用上篇博文介绍了继承的相关知识,就可以得到第三个版本面向对象的程序,代码如下:
// JavaScript Document
function LimitDrag(id)//得到Drag的属性
{
Drag.call(this,id);
};
for(var i in Drag.prototype)
{
LimitDrag.prototype[i]=Drag.prototype[i];
}
//重写Drag的fnMove方法
LimitDrag.prototype.fnMove=function(ev)
{
var oEvent = ev||event;
var l=oEvent.clientX - this.disX;
var t=oEvent.clientY - this.disY;
/*
以下的一些判断处理时防止拖拽被拖出界面之外
*/
if(l<0)//限制不能移出界面的左边
{
l=0;
}
else if(l>document.documentElement.clientWidth-this.oDiv.offsetWidth)//限制不能移出界面的右边
{
l=document.documentElement.clientWidth-this.oDiv.offsetWidth;
}
this.oDiv.style.left=l+'px';
if(t<0)//限制不能移出界面的上边
{
t=0;
}
else if(t>document.documentElement.clientHeight-this.oDiv.offsetHeight)//限制不能移出界面的下边
{
t=document.documentElement.clientHeight-this.oDiv.offsetHeight;
}
this.oDiv.style.top=t+'px';
};
以上就是关于拖拽用面向对象和继承相关知识来实现。