Top

拖拽系列二、利用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         width: 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

作者:Avenstar

出处:http://www.cnblogs.com/zjf-1992/p/6854783.html

关于作者:专注于前端开发、喜欢阅读

本文版权归作者所有,转载请标明原文链接

posted @ 2017-05-15 08:07  Avenstar  阅读(626)  评论(0编辑  收藏