前面的几篇拖拽文章是常规的写法,本文用面向对象的方式重写拖拽,然后继承出限制范围的拖拽。
父类
面向对象,假设构造函数为Drag,继承出的限制范围的拖拽为LimitDrag。
既然面向对象,就得有属性和方法。
属性:要拖拽的div,要保存的距离disX 和 disY;
方法:三个事件–down,move,up;
方法用原型的方式共享。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>面向对象的拖拽</title>
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
background: orange;
position: absolute;
}
</style>
</head>
<body>
<div id="div1"></div>
<script type="text/javascript">
function Drag(id) {
var _this = this;
this.oDiv = document.getElementById(id);
this.disX = 0;
this.disY = 0;
//this.oDiv.onmousedown = this.fnDown;
//上面注释的代码中this.fnDown中的this指的是this.oDiv,
//而不是Drag,所以要先把Drag的this保存起来_this
this.oDiv.onmousedown = function(ev) {
console.log(this);//oDiv
_this.fnDown(ev);
};
}
Drag.prototype.fnDown = function(ev) {
var _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() {
_this.fnUp();
};
};
Drag.prototype.fnMove = function(ev) {
var oEvent = ev || event;
var l = oEvent.clientX - this.disX;
var t = oEvent.clientY - this.disY;
this.oDiv.style.cssText = ';left:' + l + 'px;top:' + t + 'px;';
}
Drag.prototype.fnUp = function() {
document.onmousemove = null;
document.onmouseup = null;
};
new Drag('div1');
</script>
</body>
</html>
继承
属性的继承用call欺骗方式,方法的继承用复制prototype的方式,因为prototype是对象,引用型变量,这里得注意!
Drag.js:
function Drag(id) {
var _this = this;
this.oDiv = document.getElementById(id);
this.disX = 0;
this.disY = 0;
this.oDiv.onmousedown = function(ev) {
console.log(this);
_this.fnDown(ev);
return false;//阻止浏览器的一些默认行为bug
};
}
Drag.prototype._getStyle = function(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, null)[attr];
}
}
Drag.prototype.fnDown = function(ev) {
var _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() {
_this.fnUp();
};
};
Drag.prototype.fnMove = function(ev) {
var oEvent = ev || event;
var l = oEvent.clientX - this.disX;
var t = oEvent.clientY - this.disY;
this.oDiv.style.cssText = ';left:' + l + 'px;top:' + t + 'px;';
}
Drag.prototype.fnUp = function() {
document.onmousemove = null;
document.onmouseup = null;
};
LimitDrag:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>继承</title>
<script type="text/javascript" src="./Drag.js"></script>
<style type="text/css">
#div1 {
width: 100px;
height: 100px;
background: orange;
position: absolute;
}
</style>
</head>
<body>
<div id="div1"></div>
<script type="text/javascript">
function LimitDrag(id) {
Drag.call(this, id);//除了this,一定要考虑原有的参数
}
/*
prototype属性是个对象,对象是引用型变量,不会复制,变量名都指向同一块内存地址
LimitDrag.prototype = Drag.prototype;如果这么写的话,两者都指向同一块内存地址
改动了两者都受影响,注意引用类型和基本类型的区别!
*/
for (var i in Drag.prototype) {
LimitDrag.prototype[i] = Drag.prototype[i];
}
//重写覆盖父类的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 - parseInt(this._getStyle(this.oDiv, 'width'))/*this.oDiv.offsetWidth*/) {
l = document.documentElement.clientWidth - parseInt(this._getStyle(this.oDiv, 'width'))/*this.oDiv.offsetWidth*/;
}
if (t < 0) {
t = 0;
} else if (t > document.documentElement.clientHeight - this.oDiv.offsetHeight) {
t = document.documentElement.clientHeight - this.oDiv.offsetHeight;
}
this.oDiv.style.cssText = ';left:' + l + 'px;top:' + t +'px;';
};
new LimitDrag('div1');
</script>
</body>
</html>