首先,是最基本的面向过程的拖拽代码
/*css*/
<style>
#box{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
/*html*/
<div id="box"></div>
/*js*/
<script>
window.onload=function(){
var oDiv=document.getElementById('box');
var disX=0;
var disY=0;
oDiv.onmousedown=function(event){
//获取事件对象
var event=event||window.event;
// disX相当于鼠标到div左侧的距离,同理disY
disX=event.clientX-oDiv.offsetLeft;
disY=event.clientY-oDiv.offsetTop;
document.onmousemove=function(event){
var event=event||window.event;
oDiv.style.left=event.clientX-disX+'px';
oDiv.style.top=event.clientY-disY+'px';
}
document.onmouseup=function () {
// 鼠标释放时事件清空
document.onmousemove=null;
document.onmouseup=null;
}
return false;
}
}
</script>
开始改写版本一
尽量不要出现函数嵌套函数
- 可以有全局变量
- 把onload中不是赋值的语句放在单独函数中
<script>
var oDiv=null;
var disX=0;
var disY=0;
window.onload=function(){
oDiv=document.getElementById('box');
init()
}
function init() {
oDiv.onmousedown=fnDown;
}
function fnDown(event){
var event=event||window.event;
disX=event.clientX-oDiv.offsetLeft;
disY=event.clientY-oDiv.offsetTop;
document.onmousemove=fnMove;
document.onmouseup=fnUp;
return false;
}
function fnMove(event){
var event=event||window.event;
oDiv.style.left=event.clientX-disX+'px';
oDiv.style.top=event.clientY-disY+'px';
}
function fnUp() {
document.onmousemove=null;
document.onmouseup=null;
}
</script>
面向对象的改写 es5
- 全局变量就是属性
- 函数就是方法
- onload中创建对象
- 改this指向问题
在ie和谷歌下,这样是可以的,但是火狐下,应为有些地方为了this指向 嵌套了一层函数,但火狐可不这样,他认为event是事件函数传递的,也就是事件后面更着的函数,这是好就需要把event当做参数传递了
<script>
window.onload=function(){
var d=new Drag('box');
d.init();
}
//构造函数
function Drag(id) {
this.disX=0;
this.disY=0;
this.oDiv=document.getElementById(id);
}
Drag.prototype.init=function () {
// 这里的this 指向的是Drag这个类
var _this=this;
this.oDiv.onmousedown=function () { //这里嵌套一层是为了解决若写成this.fnDown的话,下面fnDown里面的this就会变成this.oDiv,相当于this就变成div了
// 匿名函数里的this是指window,因为this指的是调用他的对象,但是匿名函数不知道是谁调用的,所以可以认为是被window调用的
_this.fnDown()
};
}
Drag.prototype.fnDown=function (event) {
var event=event||window.event;
this.disX=event.clientX-this.oDiv.offsetLeft;
this.disY=event.clientY-this.oDiv.offsetTop;
var _this=this;
document.onmousemove=function () {
_this.fnMove()
};
document.onmouseup=this.fnUp;
return false;
}
Drag.prototype.fnMove=function (event) {
var event=event||window.event;
this.oDiv.style.left=event.clientX- this.disX+'px';
this.oDiv.style.top=event.clientY- this.disY+'px';
}
Drag.prototype.fnUp=function () {
document.onmousemove=null;
document.onmouseup=null;
}
</script>
但是火狐下报错:TypeError: event is undefined
火狐的解决办法
<script>
window.onload = function () {
var d = new Drag('box');
d.init();
}
//构造函数
function Drag(id) {
this.disX = 0;
this.disY = 0;
this.oDiv = document.getElementById('box');
}
Drag.prototype.init = function () {
var _this = this;
this.oDiv.onmousedown = function (event) { //嵌套是为了解决this问题
var event = event || window.event;
_this.fnDown(event)
};
}
Drag.prototype.fnDown = function (event) {
this.disX = event.clientX - this.oDiv.offsetLeft;
this.disY = event.clientY - this.oDiv.offsetTop;
var _this = this;
document.onmousemove = function (event) {
_this.fnMove(event)
};
document.onmouseup = this.fnUp;
return false;
}
Drag.prototype.fnMove = function (event) {
this.oDiv.style.left = event.clientX - this.disX + 'px';
this.oDiv.style.top = event.clientY - this.disY + 'px';
}
Drag.prototype.fnUp = function () {
document.onmousemove = null;
document.onmouseup = null;
}
</script>
也可以吧init 放进构造函数里面,这样只要new 一个就可以生成拖拽了
,如下所示
<script>
window.onload=function(){
var d=new Drag('box');
}
//构造函数
function Drag(id) {
var _this=this;
this.disX=0;
this.disY=0;
this.oDiv=document.getElementById('box');
this.oDiv.onmousedown=function (event) { //嵌套是为了解决this问题
var event=event||window.event;
_this.fnDown(event)
};
}
Drag.prototype.fnDown=function (event) {
this.disX=event.clientX-this.oDiv.offsetLeft;
this.disY=event.clientY-this.oDiv.offsetTop;
var _this=this;
document.onmousemove=function (event) {
_this.fnMove(event)
};
document.onmouseup=this.fnUp;
return false;
}
Drag.prototype.fnMove=function (event) {
this.oDiv.style.left=event.clientX- this.disX+'px';
this.oDiv.style.top=event.clientY- this.disY+'px';
}
Drag.prototype.fnUp=function () {
document.onmousemove=null;
document.onmouseup=null;
}
</script>
es6 面向对象的改写,也可以吧init 放进构造函数里面
<script>
window.onload = function () {
var d = new Drag('box');
d.init();
}
// 类
class Drag {
//构造函数
constructor(id) {
this.disX = 0;
this.disY = 0;
this.oDiv = document.getElementById(id);
}
init() {
var _this = this;
this.oDiv.onmousedown = function (event) {
var event = event || window.event;
_this.fnDown(event)
};
}
fnDown(event) {
this.disX = event.clientX - this.oDiv.offsetLeft;
this.disY = event.clientY - this.oDiv.offsetTop;
var _this = this;
document.onmousemove = function (event) {
_this.fnMove(event)
};
document.onmouseup = this.fnUp;
return false;
}
fnMove(event) {
this.oDiv.style.left = event.clientX - this.disX + 'px';
this.oDiv.style.top = event.clientY - this.disY + 'px';
}
fnUp() {
document.onmousemove = null;
document.onmouseup = null;
}
}
</script>
总结
- 原则
先写出普通的写法,然后改写成面向对象的写法普通方法变形
- 尽量不要出现函数嵌套函数
- 可以有全局变量
- 把onload中不是赋值的语句放在单独函数中
改写面向对象
- 全局变量就是属性
- 函数就是方法
- onload中创建对象
- 改this指向问题