先对其中的一些将要使用到的event对象及属性进行说明:
event.clientX、event.clientY
鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性。
offsetLeft、offsetTop
规定元素相对于其有定位的父类距离其左侧与顶部的距离,如果父类没有定位,则相对于body取左侧与顶部距离。
document.documentElement.clientWidth、document.documentElement.clientHeight
获得的是屏幕可视区域的宽高,不包括滚动条与工具条。
offsetWidth、offsetHeight
获取元素的宽度与高度。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>面向对象继承实现拖拽</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box{
position: absolute;
left: 0;
width: 100px;
height: 100px;
background: #00FF7F;
}
#box1{
position: absolute;
left: 100px;
width: 100px;
height: 100px;
background: #0366D6;
}
</style>
<script>
window.onload = function(){
var obox = new Drag('box');
var obox1 = new Cdrag('box1');
obox.init();
obox1.init();
}
//定义一个拖拽的对象
function Drag(id){
this.box = document.getElementById(id);
this.disx = 0;
this.disy = 0;
}
Drag.prototype.init = function(){
var _this = this;//鼠标事件里面的this是指向调用它的box,因为需要一个中间变量来转变this的指向
this.box.onmousedown = function(ev){
_this.fndown(ev);//ev是针对事件的,这里要作为一个参数传入
}
}
Drag.prototype.fndown = function(ev){
var _this = this;//鼠标事件里面的this是指向调用它的box,因为需要一个中间变量来转变this的指向
var ev = ev || window.event;
this.disx = ev.clientX - this.box.offsetLeft;
this.disy = ev.clientY - this.box.offsetTop;
document.onmousemove = function(ev){
_this.fnmove(ev);
};
document.onmouseup = function(){
_this.fnup();
};
return false;
}
Drag.prototype.fnmove = function(ev){
var ev = ev || window.event;
this.box.style.left = ev.clientX - this.disx + 'px';//clientX/offsetLeft/offsetWidth这些是没有单位返回的,只有数字,因此需要添加单位
this.box.style.top = ev.clientY - this.disy + 'px';
}
Drag.prototype.fnup = function(){
document.onmousedown = null;
document.onmousemove = null;
}
//子类继承父类
function Cdrag(id){
Drag.call(this,id);//通过call方法继承父类属性
}
for(var i in Drag.prototype){//通过循环继承父类的方法
Cdrag.prototype[i] = Drag.prototype[i];
}
Cdrag.prototype.fnmove = function(ev){
var ev = ev || window.event;
var l = ev.clientX - this.disx;
var t = ev.clientY - this.disy;
//添加了子类自己的特性,给定一个范围内拖拽
if(l < 0){
l = 0;
}else if(l > document.documentElement.offsetWidth - this.box.offsetWidth){//整个窗口减去元素的宽度,就得到边界范围
l = document.documentElement.offsetWidth - this.box.offsetWidth;
}
if(t < 0){
t = 0;
}else if(t > document.documentElement.clientHeight - this.box.offsetHeight){//整个窗口减去元素的高度,就得到边界范围
t = document.documentElement.clientHeight - this.box.offsetHeight;
}
this.box.style.left = l + 'px';
this.box.style.top = t + 'px';
}
</script>
</head>
<body>
<div id="box"></div>
<div id="box1"></div>
</body>
</html>
实现这个拖拽动态效果主要的问题还是要明确其中使用到的各种距离取值事件或者属性,在各个属性不明确的情况,比较难理解整个实现过程,也比较难以记住,再现整个流程。