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

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

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

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

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

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

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

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

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

3.普通函数模块化

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

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

被拖拽的目标元素对象有

①鼠标按下时mousedown;

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

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

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

代码大致结构如下

 /*
* 利用OOP(面向对象) 实现拖拽代码的封装
*/
;(function(){
//事件处理程序
//elem DOM对象 eventName 事件名称 eventType 事件类型
function eventHandler(elem, eventName, eventType){};
//移除事件兼容处理
function removeEventHandler(elem, eventName, eventType){}
//获取style属性值
function getStyleValue(elem, property){}
//被拖拽构造函数
function Drag(selector){
//elem DOM对象
this.elem = typeof selector === 'object' ? selector : document.getElementById(selector);
//元素初始化位置
this.initObjX = 0;
this.initObjY = 0;
//鼠标初始化位置
this.initMouseX = 0;
this.initMouseY = 0;
this.isDraging = false;
//初始化--鼠标事件操作
this._init();
}
//Drag对象原型
Drag.prototype = {
constructor : Drag,
//初始化
//构造原型指回Drag 等价于==>>Drag.prototype._init = function(){}
_init : function(){
this.setDrag();
},
//获取目标元素pos位置
getObjPos : function(elem) {},
//设置被拖动元素的位置
setObjPos : function (elem, pos){},
//设置目标元素事件及操作流程
setDrag : function(){}
}
//将Drag挂到全局对象window上
window.Drag = Drag;
})();

    实现拖拽功能函数的详述

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

 //被拖拽构造函数
function Drag(selector){
//elem DOM对象
this.elem = typeof selector === 'object' ? selector : document.getElementById(selector);
//元素初始化位置
this.initObjX = 0;
this.initObjY = 0;
//鼠标初始化位置
this.initMouseX = 0;
this.initMouseY = 0;
this.isDraging = false;
//初始化--鼠标事件操作
this._init();
}
//Drag对象原型
Drag.prototype = {
constructor : Drag,
//初始化
//构造原型指回Drag 等价于==>>Drag.prototype._init = function(){}
_init : function(){
this.setDrag();
},
//设置目标元素事件及操作流程
setDrag : function(){
//目标元素对象
var self = this;
var time = null; //定时器
function mousedown(event){
event = window.event || event;
//鼠标按下时位置
this.initMouseX = event.clientX;
this.initMouseY = event.clientY;
//获取元素初始化位置pos
var pos = self.getObjPos(self.elem);
this.initObjX = pos.x;
this.initObjY = pos.y;
//mousemove
time = setTimeout(function(){ //缓解移动卡顿
eventHandler(self.elem, mousemove, "mousemove");
}, 25);
//mouseup
eventHandler(self.elem, mouseup, "mouseup");
//按下标识
self.isDraging = true;
}
function mousemove(event){
event = window.event || event;
if(self.isDraging){
//元素移动位置 == 当前鼠标移动位置 - 鼠标按下位置 + 目标元素初始化位置
var moveX = event.clientX - this.initMouseX + this.initObjX;
var moveY = event.clientY - this.initMouseY + this.initObjY;
//设置拖拽元素位置
self.setObjPos(self.elem, {
x : moveX,
y : moveY,
});
}
}
function mouseup(event){
event = window.event || event;
self.isDraging = false;
clearTimeout(time);
//移除事件
removeEventHandler(document, mousemove, 'mousemove');
removeEventHandler(document, mouseup, 'mouseup');
}
//mousedown
eventHandler(this.elem, mousedown, "mousedown");
}
}

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

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

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

HTML代码

 <style>
body {
margin: 0;
padding: 0;
position: relative;
}
.box {
width: 100px;
height: 100px;
background: deeppink;
position: absolute;
left: 25px;
top: 25px;
cursor: move;
}
</style>
<div class="box" id="box" style="position: absolute;left: 25px;top: 25px;"></div>
<script src="js/draging.js"></script>
<script type="text/javascript">
window.onload = function(){
new Drag(document.getElementById("box"));
}
</script>

draging.js

 /*
* 利用JS面向对象OOP思想实现拖拽封装
*/
;(function(){
//事件处理程序
//elem DOM对象 eventName 事件名称 eventType 事件类型
function eventHandler(elem, eventName, eventType){
// elem.attachEvent 兼容IE9以下事件
elem.addEventListener ? elem.addEventListener(eventType, eventName, false) : elem.attachEvent('on'+eventType, eventName);
};
//移除事件兼容处理
function removeEventHandler(elem, eventName, eventType){
elem.removeEventListener ? elem.removeEventListener(eventType, eventName) : elem.detachEvent(eventType, eventName);
}
//获取style属性值
function getStyleValue(elem, property){
//getComputedStyle、currentStyle 返回CSS样式声明对象([object CSSStyleDeclaration]) 只读
//getComputedStyle 支持IE9+以上及正常浏览器
//currentStyle 兼容IE8及IE8以下获取目标元素style样式
return window.getComputedStyle(elem,null) ? window.getComputedStyle(elem,null)[property] : elem.currentStyle[property];
}
//被拖拽构造函数
function Drag(selector){
//elem DOM对象
this.elem = typeof selector === 'object' ? selector : document.getElementById(selector);
//元素初始化位置
this.initObjX = 0;
this.initObjY = 0;
//鼠标初始化位置
this.initMouseX = 0;
this.initMouseY = 0;
this.isDraging = false;
//初始化--鼠标事件操作
this._init();
}
//Drag对象原型
Drag.prototype = {
constructor : Drag,
//初始化
//构造原型指回Drag 等价于==>>Drag.prototype._init = function(){}
//初始化鼠标事件及鼠标操作流程
_init : function(){
this.setDrag();
},
//获取目标元素pos位置
getObjPos : function(elem) {
var pos = {x: 0, y: 0};
if(getStyleValue(elem, 'position') == 'static') {
this.elem.style.position = 'relative';
return pos;
} else {
var x = parseInt(getStyleValue(elem, 'left') ? getStyleValue(elem, 'left') : 0);
var y = parseInt(getStyleValue(elem, 'top') ? getStyleValue(elem, 'top') : 0);
return pos = {
x: x,
y: y
}
}
},
//设置被拖动元素的位置
setObjPos : function (elem, pos){
elem.style.position = 'absolute';
elem.style.left = pos.x+'px';
elem.style.top = pos.y+'px';
},
//设置目标元素事件及操作流程
setDrag : function(){
//目标元素对象
var self = this;
var time = null; //定时器
function mousedown(event){
event = window.event || event;
//鼠标按下时位置
this.initMouseX = event.clientX;
this.initMouseY = event.clientY;
//获取元素初始化位置pos
var pos = self.getObjPos(self.elem);
this.initObjX = pos.x;
this.initObjY = pos.y;
//mousemove
time = setTimeout(function(){ //缓解移动卡顿
eventHandler(self.elem, mousemove, "mousemove");
}, 25);
//mouseup
eventHandler(self.elem, mouseup, "mouseup");
//按下标识
self.isDraging = true;
}
function mousemove(event){
event = window.event || event;
if(self.isDraging){
//元素移动位置 == 当前鼠标移动位置 - 鼠标按下位置 + 目标元素初始化位置
var moveX = event.clientX - this.initMouseX + this.initObjX;
var moveY = event.clientY - this.initMouseY + this.initObjY;
//设置拖拽元素位置
self.setObjPos(self.elem, {
x : moveX,
y : moveY,
});
}
}
function mouseup(event){
event = window.event || event;
self.isDraging = false;
clearTimeout(time);
//移除事件
removeEventHandler(document, mousemove, 'mousemove');
removeEventHandler(document, mouseup, 'mouseup');
}
//mousedown
eventHandler(this.elem, mousedown, "mousedown");
}
}
//将Drag挂到全局对象window上
window.Drag = Drag;
})();

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

作者:Avenstar

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

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

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

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

  1. Java面向对象OOP思想概述

    目录 OOP思想(Object Oriented Programming) 类和对象 接口 抽象类 OOP三大特性 封装 继承 多态 OOP复用的形式 OOP思想(Object Oriented Pr ...

  2. js面向对象oop编程

    理解对象 对象这个词如雷贯耳,同样出名的一句话:XXX语言中一切皆为对象! 对象究竟是什么?什么叫面向对象编程? 对象(object),台湾译作物件,是面向对象(Object Oriented)中的术 ...

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

    现实世界的对象由形态和行为组成,js中对应的是属性和函数. <!DOCTYPE html> <html> <head> <meta charset=" ...

  4. 面向对象oop思想

    OOP核心思想:封装,继承,多态. 理解: 对象是由数据和容许的操作组成的封装体,与客观实体有直接对应关系,一个对象类定义了具有相似性质的一组对象.而每继承性是对具有层次关系的类的属性和操作进行共享的 ...

  5. JS面向对象编程(一):封装

    js是一门基于面向对象编程的语言.      如果我们要把(属性)和(方法)封装成一个对象,甚至要从原型对象生成一个实例,我们应该怎么做呢?  一.生成对象的原始模式            假定把猫看 ...

  6. JavaScript面向对象OOP思想Class系统

    JavaScript的Class模块,纯天然无依赖,只有2k大小,快速高效,让我们优雅的面向对象... | |目录 1源码:jClass.js 2源码:jClass.min.js 3构建一个类 4访问 ...

  7. js面向对象编程(一):封装(转载)

    一. 生成对象的原始模式 假定我们把猫看成一个对象,它有"名字"和"颜色"两个属性. var Cat = { name : '', color : '' } 现 ...

  8. js面向对象编程思想

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  9. [js]面向对象编程

    一.js面向对象基本概念 对象:内部封装.对外预留接口,一种通用的思想,面向对象分析: 1.特点 (1)抽象 (2)封装 (3)继承:多态继承.多重继承 2.对象组成 (1)属性: 任何对象都可以添加 ...

随机推荐

  1. 认识J2SE

    1. J2SE的定义 J2SE:全称为Java 2 Standard Edition.Java 2平台包括:标准版(J2SE).企业版(J2EE)和微缩版(J2ME)三个版本. J2SE主要包括UI. ...

  2. CrawlScript脚本语言实现网络爬虫

    前段时间我们学习了几种爬虫技术,我们来回顾一下,webCollector,htmlParser,Jsoup,各有优劣,但是如果能灵活运用,其实都是很不错的.那么,今天呢,我们来学习一种脚本语言,这是一 ...

  3. TensorFlow 安装详解

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! 『不要把手段当成目标 — <一个瑜伽行者的自传>』   本文提纲 1. 机器学习 2 ...

  4. 一个GOOD的Idea需要伯乐发觉-致敬错过的IDEA

    类似一个微信电话本

  5. .NET中数据访问方式(一):LINQ

    语言集成查询(Language-Integrated Query),简称LINQ,.NET中的LINQ体系如下图所示:   在编程语言层次,LINQ对于不同的数据源提供了相同的查询语法,方便了程序员操 ...

  6. 1137: 零起点学算法44——多组测试数据输出II

    1137: 零起点学算法44--多组测试数据输出II Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: ...

  7. 从零开始用 Flask 搭建一个网站(二)

    从零开始用 Flask 搭建一个网站(一) 介绍了如何搭建 Python 环境,以及 Flask 应用基本项目结构.我们要搭建的网站是管理第三方集成的控制台,类似于 Slack. 本篇主要讲解数据如何 ...

  8. 《Python自然语言处理》第一章-练习17

    问题描述: 使用text9.index()查找词sunset的索引值.你需要将这个词作为一个参数插入到圆括号之间.通过尝试和出错的过程中,找到完整的句子中包含这个词的切片. 解题思路: 用两个集合,一 ...

  9. 前端随手优化不完全篇-SEO篇

    一代码优化概述 关于代码优化的知识是纯理论的知识,学习的很枯燥.在学到CSS时,不免遇到CSS+div进行代码优化的知 识,因此在网上看了一些关于这方面的知识,简单的整合一下,梳理自己所了解的代码优化 ...

  10. vue.js2.0新手笔记(一)——安装

    知道vue很长时间了,一直只是了解,没有深入学习,也没做什么具体的东西.现在有时间了,决定重头好好学一下,就从安装开始吧. 一.安装node vue是用npm安装,npm是node的一个包管理工具,所 ...