zoukankan      html  css  js  c++  java
  • 拖拽系列二、利用JS面向对象OOP思想实现拖拽封装

    接着上一篇拖拽系列一、JavaScript实现简单的拖拽效果这一篇博客将接着对上一节实现代码利用JS面向对象(OOP)思维对上一节代码进行封装;

    使其模块化、避免全局函数污染、方便后期维护和调用;写到这里突然想起一句话“没有任何一个题目是彻底完成的。总还会有很多事情可做......”

    我想这句话程序开发大概也适用吧,前端开发人员总是可以结合自己之前学到“拖拽”相关知识,不断扩展、完善、无穷无尽.......

        利用匿名函数自执行实现封装

    ;(function(){
       //do something......
    })();

    这样写的好处是避免全局变量、全局函数的污染;原因是函数存在作用域、作用域链、执行上下文;分号作用是避免代码压缩出错问题

        面向对象(OOP)及代码大致结构简述

    1.构造函数主要用于构造实例化的对象,每个对象都有自己特有(私有)的属性和方法(该属性和方法只供当前实例化对象调用);

    2.对象原型通过调用构造函数实例化对象对属性与方法的实现共享

    3.普通函数模块化

    面向对象(OOP)思维分析拖拽

    重复说明——理解拖拽的核心就是掌握鼠标相关事件及鼠标事件相关联的操作流程

    被拖拽的目标元素对象有

    ①鼠标按下时mousedown;

           初始化鼠标的位置initMouseX、initMouseY;初始化目标元素位置initObjX、initObjY;鼠标按下标识isDraging

    ②鼠标移动时mousemove; 获取鼠标移动时的位置、计算目标元素的移动距离、设置目标元素的距离

    ③鼠标离开时mouseup; 停止移动,移除目标元素事件绑定;

    代码大致结构如下

    复制代码
     1 /*
     2  * 利用OOP(面向对象) 实现拖拽代码的封装
     3  */
     4 ;(function(){
     5     //事件处理程序
     6     //elem DOM对象  eventName 事件名称  eventType 事件类型
     7     function eventHandler(elem, eventName, eventType){};
     8     //移除事件兼容处理
     9     function removeEventHandler(elem, eventName, eventType){}
    10     //获取style属性值
    11     function getStyleValue(elem, property){}
    12     //被拖拽构造函数
    13     function Drag(selector){
    14         //elem DOM对象
    15         this.elem = typeof selector === 'object' ? selector : document.getElementById(selector);
    16         //元素初始化位置
    17         this.initObjX = 0;
    18         this.initObjY = 0;
    19         //鼠标初始化位置
    20         this.initMouseX = 0;
    21         this.initMouseY = 0;
    22         this.isDraging = false;
    23         //初始化--鼠标事件操作
    24         this._init();
    25     }
    26     //Drag对象原型
    27     Drag.prototype = {
    28         constructor : Drag,  
    29         //初始化
    30         //构造原型指回Drag 等价于==>>Drag.prototype._init = function(){}
    31         _init : function(){ 
    32             this.setDrag();
    33         },
    34         //获取目标元素pos位置
    35         getObjPos : function(elem) {},
    36         //设置被拖动元素的位置
    37         setObjPos : function (elem, pos){},
    38         //设置目标元素事件及操作流程
    39         setDrag : function(){}
    40     }
    41     //将Drag挂到全局对象window上
    42     window.Drag = Drag;
    43 })();
    复制代码

        实现拖拽功能函数的详述

    上述较复杂思路集中在构造函数Drag创建被拖拽目标元素实例化对象,初始化设置目标元素鼠标事件及操作流程上,细节代码如下

    复制代码
     1 //被拖拽构造函数
     2     function Drag(selector){
     3         //elem DOM对象
     4         this.elem = typeof selector === 'object' ? selector : document.getElementById(selector);
     5         //元素初始化位置
     6         this.initObjX = 0;
     7         this.initObjY = 0;
     8         //鼠标初始化位置
     9         this.initMouseX = 0;
    10         this.initMouseY = 0;
    11         this.isDraging = false;
    12         //初始化--鼠标事件操作
    13         this._init();
    14     }
    15     //Drag对象原型
    16     Drag.prototype = {
    17         constructor : Drag,  
    18         //初始化
    19         //构造原型指回Drag 等价于==>>Drag.prototype._init = function(){}
    20         _init : function(){ 
    21             this.setDrag();
    22         },
    23         //设置目标元素事件及操作流程
    24         setDrag : function(){
    25             //目标元素对象
    26             var self =  this;
    27             var time = null; //定时器
    28             function mousedown(event){
    29                 event = window.event || event;
    30                 //鼠标按下时位置
    31                 this.initMouseX = event.clientX;
    32                 this.initMouseY = event.clientY;
    33                 //获取元素初始化位置pos
    34                 var pos = self.getObjPos(self.elem);
    35                 this.initObjX = pos.x;
    36                 this.initObjY = pos.y;
    37                 //mousemove
    38                 time = setTimeout(function(){ //缓解移动卡顿
    39                     eventHandler(self.elem, mousemove, "mousemove");
    40                 }, 25);
    41                 //mouseup
    42                 eventHandler(self.elem, mouseup, "mouseup");
    43                 //按下标识
    44                 self.isDraging = true;
    45             }
    46             function mousemove(event){
    47                 event = window.event || event;
    48                 if(self.isDraging){
    49                     //元素移动位置 == 当前鼠标移动位置 - 鼠标按下位置 + 目标元素初始化位置 
    50                     var moveX = event.clientX - this.initMouseX +  this.initObjX;
    51                     var moveY =  event.clientY - this.initMouseY +  this.initObjY;
    52                     //设置拖拽元素位置
    53                     self.setObjPos(self.elem, {
    54                         x : moveX,
    55                         y : moveY,
    56                     });
    57                 }
    58             }
    59             function mouseup(event){
    60                 event = window.event || event;
    61                 self.isDraging = false;
    62                 clearTimeout(time);
    63                 //移除事件
    64                 removeEventHandler(document, mousemove, 'mousemove');
    65                 removeEventHandler(document, mouseup, 'mouseup');
    66             }
    67             //mousedown
    68             eventHandler(this.elem, mousedown, "mousedown");
    69         }
    70     }
    复制代码

    至于设置/获取被拖拽的目标元素就很简单咯!

    调用写法  new Drag(elem); elem为传入DOM对象即可

        JS面向对象OOP实现拖拽完整代码

    HTML代码

    复制代码
     1 <style>
     2     body {
     3         margin: 0;
     4         padding: 0;
     5         position: relative;
     6     }
     7     .box {
     8          100px;
     9         height: 100px;
    10         background: deeppink;
    11         position: absolute;
    12         left: 25px;
    13         top: 25px;
    14         cursor: move;
    15     }
    16 </style>
    17 <div class="box" id="box" style="position: absolute;left: 25px;top: 25px;"></div>
    18 <script src="js/draging.js"></script>
    19 <script type="text/javascript">
    20     window.onload = function(){
    21         new Drag(document.getElementById("box"));
    22     }            
    23 </script>
    复制代码

    draging.js

    复制代码
      1 /*
      2  * 利用JS面向对象OOP思想实现拖拽封装
      3  */
      4 ;(function(){
      5     //事件处理程序
      6     //elem DOM对象  eventName 事件名称  eventType 事件类型
      7     function eventHandler(elem, eventName, eventType){
      8         // elem.attachEvent 兼容IE9以下事件
      9         elem.addEventListener ? elem.addEventListener(eventType, eventName, false) : elem.attachEvent('on'+eventType, eventName);
     10     };
     11     //移除事件兼容处理
     12     function removeEventHandler(elem, eventName, eventType){
     13         elem.removeEventListener ? elem.removeEventListener(eventType, eventName) : elem.detachEvent(eventType, eventName);
     14     }
     15     //获取style属性值
     16     function getStyleValue(elem, property){
     17         //getComputedStyle、currentStyle 返回CSS样式声明对象([object CSSStyleDeclaration]) 只读
     18         //getComputedStyle 支持IE9+以上及正常浏览器
     19         //currentStyle 兼容IE8及IE8以下获取目标元素style样式
     20         return window.getComputedStyle(elem,null) ? window.getComputedStyle(elem,null)[property] : elem.currentStyle[property];
     21     }
     22     //被拖拽构造函数
     23     function Drag(selector){
     24         //elem DOM对象
     25         this.elem = typeof selector === 'object' ? selector : document.getElementById(selector);
     26         //元素初始化位置
     27         this.initObjX = 0;
     28         this.initObjY = 0;
     29         //鼠标初始化位置
     30         this.initMouseX = 0;
     31         this.initMouseY = 0;
     32         this.isDraging = false;
     33         //初始化--鼠标事件操作
     34         this._init();
     35     }
     36     //Drag对象原型
     37     Drag.prototype = {
     38         constructor : Drag,  
     39         //初始化
     40         //构造原型指回Drag 等价于==>>Drag.prototype._init = function(){}
     41         //初始化鼠标事件及鼠标操作流程
     42         _init : function(){ 
     43             this.setDrag();
     44         },
     45         //获取目标元素pos位置
     46         getObjPos : function(elem) {
     47             var pos = {x: 0, y: 0};
     48             if(getStyleValue(elem, 'position') == 'static') {
     49                 this.elem.style.position = 'relative';
     50                 return pos;
     51             } else {
     52                 var x = parseInt(getStyleValue(elem, 'left') ? getStyleValue(elem, 'left') : 0);
     53                 var y = parseInt(getStyleValue(elem, 'top') ? getStyleValue(elem, 'top') : 0);
     54                 return pos = {
     55                     x: x,
     56                     y: y
     57                 }
     58             }
     59         },
     60         //设置被拖动元素的位置
     61         setObjPos : function (elem, pos){
     62             elem.style.position = 'absolute';
     63             elem.style.left = pos.x+'px';
     64             elem.style.top = pos.y+'px';
     65         },
     66         //设置目标元素事件及操作流程
     67         setDrag : function(){
     68             //目标元素对象
     69             var self =  this;
     70             var time = null; //定时器
     71              function mousedown(event){
     72                 event = window.event || event;
     73                 //鼠标按下时位置
     74                 this.initMouseX = event.clientX;
     75                 this.initMouseY = event.clientY;
     76                 //获取元素初始化位置pos
     77                 var pos = self.getObjPos(self.elem);
     78                 this.initObjX = pos.x;
     79                 this.initObjY = pos.y;
     80                 //mousemove
     81                 time = setTimeout(function(){ //缓解移动卡顿
     82                     eventHandler(self.elem, mousemove, "mousemove");
     83                 }, 25);
     84                 //mouseup
     85                 eventHandler(self.elem, mouseup, "mouseup");
     86                 //按下标识
     87                 self.isDraging = true;
     88             }
     89             function mousemove(event){
     90                 event = window.event || event;
     91                 if(self.isDraging){
     92                     //元素移动位置 == 当前鼠标移动位置 - 鼠标按下位置 + 目标元素初始化位置 
     93                     var moveX = event.clientX - this.initMouseX +  this.initObjX;
     94                     var moveY =  event.clientY - this.initMouseY +  this.initObjY;
     95                     //设置拖拽元素位置
     96                     self.setObjPos(self.elem, {
     97                         x : moveX,
     98                         y : moveY,
     99                     });
    100                 }
    101             }
    102             function mouseup(event){
    103                 event = window.event || event;
    104                 self.isDraging = false;
    105                 clearTimeout(time);
    106                 //移除事件
    107                 removeEventHandler(document, mousemove, 'mousemove');
    108                 removeEventHandler(document, mouseup, 'mouseup');
    109             }
    110             //mousedown
    111             eventHandler(this.elem, mousedown, "mousedown");
    112         }
    113     }
    114     //将Drag挂到全局对象window上
    115     window.Drag = Drag;
    116 })();
    复制代码

    在线编辑代码请点击 http://jsrun.net/uukKp/edit

  • 相关阅读:
    使用createDocumentFragment的渲染数据(节省性能)
    面向对象写法模板
    面向对象this指向
    js 3D图片叠加旋转切换
    三列布局-中间固定俩边自适应-和两边固定中间自适应布局
    游戏中抽奖的算法
    c++11:lambda表达式
    c++11:模板
    c++11:左值、右值
    游戏服务器语言之争
  • 原文地址:https://www.cnblogs.com/libin-1/p/6858579.html
Copyright © 2011-2022 走看看