拖拽系列2、利用JS面向對象OOP思想實現拖拽封裝

接着上一篇拖拽系列1、JavaScript實現簡單的拖拽效果這一篇博客將接着對上一節實現代碼利用JS面向對象(OOP)思惟對上一節代碼進行封裝;javascript

使其模塊化、避免全局函數污染、方便後期維護和調用;寫到這裏忽然想起一句話「沒有任何一個題目是完全完成的。總還會有不少事情可作......」html

我想這句話程序開發大概也適用吧,前端開發人員老是能夠結合本身以前學到「拖拽」相關知識,不斷擴展、完善、無窮無盡.......前端

    利用匿名函數自執行實現封裝

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

這樣寫的好處是避免全局變量、全局函數的污染;緣由是函數存在做用域、做用域鏈、執行上下文;分號做用是避免代碼壓縮出錯問題java

    面向對象(OOP)及代碼大體結構簡述

1.構造函數主要用於構造實例化的對象,每一個對象都有本身特有(私有)的屬性和方法(該屬性和方法只供當前實例化對象調用);瀏覽器

2.對象原型經過調用構造函數實例化對象對屬性與方法的實現共享模塊化

3.普通函數模塊化函數

面向對象(OOP)思惟分析拖拽this

重複說明——理解拖拽的核心就是掌握鼠標相關事件及鼠標事件相關聯的操做流程spa

被拖拽的目標元素對象有.net

①鼠標按下時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

關於做者:專一於前端開發、喜歡閱讀

本文版權歸做者全部,轉載請標明原文連接

相關文章
相關標籤/搜索