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

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

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

时间: 2025-01-03 16:50:06

拖拽系列二、利用JS面向对象OOP思想实现拖拽封装的相关文章

Javascrpt 速成篇】 二:js面向对象

现实世界的对象由形态和行为组成,js中对应的是属性和函数. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>js object</title> </head> <bod

Java学习系列(二十三)Java面向对象之内部类详解

一.前言 内部类也称寄生类,就是把一个类放在类里面(即内部类的上一级程序单元是类)定义,将其作为外部类的成员.内部类主要用几种定义形式:静态(static)内部类,非静态内部类,匿名内部类(也就是没有名字的寄生类).内部类的好处就是内部类可以直接外部类的(包括私有)成员,反之不能.下面我们通过一些实例来详细讲解一下Java中内部类的使用及几种定义形式的相互调用. 二.实例说明 (1)匿名内部类:当程序创建匿名内部类时,会立即创建匿名内部类(实现类)的实例. interface IBreathe

Java学习系列(二十)Java面向对象之反射详解

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/45289391 前言 今天讲讲Java中的反射.我们常见的反射多用于JDBC中的加载驱动程序Class.forName("com.mysql.jdbc.Driver");.Struts的MVC.Hibernate中的ORM.Spring中的IOC还有一些其他框架等等.那它有什么好处呢?它的好处就是能够动态的创建对象和编译且能够访问某个类中的所有(包括私有)属性方法及对象的属性方法

Java学习系列(二十一)Java面向对象之注解详解

转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/45295947 一.前言 Java中的注解Annotation运用到很多方面,比如之前讲的单元测试中的@Test.Spring.SpringMVC还有其他框架等等.Java本身自带的注解也有一些,比如:@Override(子类要重写/覆写父类的对应方法).@Deprecated(表示方法不建议被使用).@SuppressWarnings(抑制警告)等等.当然,我们也可以自定义一些自己需要的

js面向对象oop编程

理解对象 对象这个词如雷贯耳,同样出名的一句话:XXX语言中一切皆为对象! 对象究竟是什么?什么叫面向对象编程? 对象(object),台湾译作物件,是面向对象(Object Oriented)中的术语,既表示客观世界问题空间(Namespace)中的某个具体的事物,又表示软件系统解空间中的基本元素. 在软件系统中,对象具有唯一的标识符,对象包括属性(Properties)和方法(Methods),属性就是需要记忆的信息,方法就是对象能够 提供的服务.在面向对象(Object Oriented)

Js面向对象OOP学习指南

Type: 1.基本类型 each variable containing a primitive value uses its own storage space . tip: undefined == null true 2.引用类型

[laravel系列](二).利用composer进行项目下载

有个框架才是项目开发的第一步哦,下面我们来进行项目的下载,主要依赖于dos窗口, 1.创建项目存放目录,首先,我再D盘下创建一个文件夹abc ,用来存放我要下载的项目. 创建好后,打开dos界面(如何打开dos界面 请参考(一),) 首先输入指令   d:     (大意是进入D盘) 然后输入指令  cd abc  (大意是进入D盘下的abc文件夹) 下一个指令是最最重要的哦 ,看仔细哦 composer create- project laravel/laravel blog --prefer

5月17日上课笔记-js面向对象

二.js面向对象 js创建对象: var 对象名称 = new Object(); person.name = "小明"; //姓名 person.age = 18; person.location = "合肥"; person.showName = function(){ alert(this.name); } //调用属性 //alert(person.name); person.showName(); 字面量创建对象: JSON格式 var person={

PHP面向对象(OOP)编程完全教程

转自:http://blog.snsgou.com/post-41.html 面向对象编程(OOP)是我们编程的一项基本技能,PHP5对OOP提供了良好的支持.如何使用OOP的思想来进行PHP的高级编程,对于提高PHP编程能力和规划好Web开发构架都是非常有意义的.下面我们就通过实例来说明使用PHP的OOP进行编程的实际意义和应用方法. 我们通常在做一个有数据库后台的网站的时候,都会考虑到程序需要适用于不同的应用环境.和其他编程语言有所不同的是,在PHP中,操作数据库的是一系列的具体功能函数(如