美文网首页
从面相过程的拖拽到面向对象的拖拽

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

作者: 努力是为了选择 | 来源:发表于2018-02-21 23:01 被阅读0次

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

    
    /*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指向问题

    相关文章

      网友评论

          本文标题:从面相过程的拖拽到面向对象的拖拽

          本文链接:https://www.haomeiwen.com/subject/yzfatftx.html