从面相过程的拖拽到面向对象的拖拽

首先,是最基本的面向过程的拖拽代码


/*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指向问题
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,679评论 0 5
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,805评论 18 399
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,967评论 0 38
  • 巢因斯坦阅读 104评论 0 0
  • 起个名字真的好难,想用的都被占了,想了半天就它了! 当别人问这是谁写的?作者是谁?你可以告诉他一“就是它”写的!哈...
    就是它阅读 214评论 0 0