JavaScript原生拖拽的面向对象写法

本篇文章和上一篇介绍用面向对象的编程技术来实现tab的效果一样,也先用面向过程的编程技术来将拖拽的效果实现一遍,然后通过变型,再用面向对象的编程技术将其实现一遍,让读者在对比中学习。
拖拽的效果其实在网页开发中是一种普遍的效果,它可以让用户自定义的构造我们的系统界面,例如自定义地显示表格的列呀,自定义地设置系统的导航呀等等。
这个拖拽效果的html结构代码如下:

<div id="drag"></div>

很简单,它就是一个div块而已。它的css的代码如下:

#drag{
  width: 100px;
  height: 100px;
  background: #4693EC;
  position: absolute;
}

效果图如下:
这里写图片描述
这里需要注意的是,我们要将拖拽的对象设置为绝对定位,因为只有定位的元素才能设置它的left,top等位置值,同时绝对定位的元素不占用空间也是好处之一。
其实实现拖拽的原理很简单,就是当鼠标点中被拖拽的对象的时候,通过触发被拖拽对象的鼠标移动事件,不断地设置被拖拽对象的left值为鼠标水平移动的距离加上被拖拽对象的左边线与浏览器左边线的距离(offsetLeft),top值为鼠标竖直移动的距离加上被拖拽对象的上边线与浏览器上边线的距离(offsetTop)。代码如下:

window.onload = function () {
  var oDrag = document.getElementById('drag');

  // 过程式
  oDrag.onmousedown = function (event) {
    var disX = event.clientX - oDrag.offsetLeft;
    var disY = event.clientY - oDrag.offsetTop;
    document.onmousemove = function (event) {
      oDrag.style.left = event.clientX - disX + 'px';
      oDrag.style.top = event.clientY - disY + 'px';
    };
    document.onmouseup = function () {
      document.onmousemove = null;
      document.onmouseup = null;
    };
  }
}

以上是面向过程的代码,然后我们要将其变型:

//变型
//尽量不要出现函数嵌套函数
//可以有全局变量
//把onload中不是赋值的语句放到单独函数中
var disX = 0;
var disY = 0;
var oDrag = document.getElementById('drag');
window.onload = function () {
  init();
};
function fnMove(event) {
  oDrag.style.left = event.clientX - disX + 'px';
  oDrag.style.top = event.clientY - disY + 'px';
}
function fnUp() {
  document.onmousemove = null;
  document.onmouseup = null;
}
function fnDown(event) {
  disX = event.clientX - oDrag.offsetLeft;
  disY = event.clientY - oDrag.offsetTop;
  document.onmousemove = fnMove;
  document.onmouseup = fnUp;
}
function init() {
  oDrag.onmousedown = fnDown;
}

将其变型以后就可以将它改造成面向对象的写法了,代码如下:

//面向对象
//全局变量就是属性
//函数就是方法
//onload中创建对象

//改this指向问题 : 事件或者是定时器,尽量让面向对象中的this指向正确的对象
function Drag(id) {
  this.disX = 0;
  this.disY = 0;
  this.oDrag = document.getElementById(id);
}
Drag.prototype.fnMove = function (event) {
  this.oDrag.style.left = event.clientX - this.disX + 'px';
  this.oDrag.style.top = event.clientY - this.disY + 'px';
};
Drag.prototype.fnUp = function () {
  document.onmousemove = null;
  document.onmouseup = null;  
};
Drag.prototype.fnDown = function (event) {
  this.disX = event.clientX - this.oDrag.offsetLeft;
  this.disY = event.clientY - this.oDrag.offsetTop;
  _this = this;
  document.onmousemove = function (event) {
    _this.fnMove(event);
  };
  document.onmouseup = this.fnUp;
};
Drag.prototype.init = function () {
  _this = this;
  this.oDrag.onmousedown = function (event) {
    _this.fnDown(event);
  }
};
window.onload = function () {
  var drag = new Drag('drag');
  drag.init();
}

在将代码改造成面向对象的风格的过程中,一定要非常的注意this的指向的问题。
我在这里也额外的补充一个相关的知识点,看一下下面的代码:

function q() {
  function test() {
    console.log(this);
  }
  return test();
}
q();

函数运行后的结果是什么?很显然是打印出window对象,因为q()方法是由window对象调用的。至此,我们就成功地用面向对象的编程技术实现了拖拽的效果了。

猜你喜欢

转载自blog.csdn.net/handsome_fan/article/details/80376538