一起来写段JS drag拖动代码


Posted in Javascript onDecember 09, 2010

1、为要被拖移三个事件,onmousedown,onmousemove,onmouseup
2、在onmousemove事件中来处理被拖移元素的位置的变化,其实说白了元素要移动的距离就是鼠标两次移动之间的距离。
3、其中还包括setCapture,releaseCapture,目的就是为了被搬移的元素始终能拥有焦点。
以前大致就是以前的认识,可以参见 JS拖动技术--- 关于setCapture 这个实现,后来随着工作要求的提高,做的工作都是要跨浏览器的,所以就重新构思并参考一些开源代码做了实现。
现在大致思路可分析为以下几步,我一一为您展现。
1、 我们是为了拖移而搬移吗?当然不是,如google地图,当每次搬移后他的目的是为了计算当前空间坐标来加载地理信息。所以我这里设计了几个常见事件。以下是事件列表
onDragStart :元素发生拖移时,如果注册该事件,触发时会接收到两个参数x,y分别为被搬移元素发生拖移时的坐标
onDrag : 元素拖移过程中,如果注册该事件,触发时会接收到两个参数nx,ny拖移过程中坐标发生的偏移量
onDragEnd :元素发生结束时,如果注册该事件,触发时会接收到两个参数x,y分别为被搬移元素的当前坐标
2、 onmousedown事件应该绑定给谁?以前我都是绑定给被拖移元素的,后来发现很不灵活,现在设计为可绑定给任意不相关的元素同时实现该元素的拖动。
3、 如何来实现元素搬移过程中一直拥有焦点?因为要跨浏览器,所以就不再用setCapture之类的方法,这里换种思维,为什么元素元素搬移过程中没有了焦点呢,主要是我们把onmousemove事件注册到了被拖移的元素上,而这并不是必需的,所以当元素触发onmousedown事件后,我把onmousemove、onmouseup事件直接注册到document上,这样鼠标移到哪都会有焦点。
说完了这么多,直接看代码结构吧!

Drag = { 
obj: null, 
init: function (options) { 
options.handler.onmousedown = this.start; 
options.handler.root = options.root || options.handler; 
var root = options.handler.root; 
root.onDragStart = options.dragStart || new Function(); 
root.onDrag = options.onDrag || new Function(); 
root.onDragEnd = options.onDragEnd || new Function(); 
}, 
start: function (e) {//此时的this是handler 
var obj = Drag.obj = this; 
obj.style.cursor = 'move'; 
e = e || Drag.fixEvent(window.event); 
ex = e.pageX; 
ey = e.pageY; 
obj.lastMouseX = ex; 
obj.lastMouseY = ey; 
var x = obj.root.offsetLeft; 
var y = obj.root..offsetTop; 
obj.root.style.left = x + "px"; 
obj.root.style.top = y + "px"; 
document.onmouseup = Drag.end; 
document.onmousemove = Drag.drag; 
obj.root.onDragStart(x, y); 
}, 
drag: function (e) { 
e = e || Drag.fixEvent(window.event); 
ex = e.pageX; 
ey = e.pageY; 
var root = Drag.obj.root; 
var x = root.style.left ? parseInt(root.style.left) : 0; 
var y = root.style.top ? parseInt(root.style.top) : 0; 
var nx = ex - Drag.obj.lastMouseX + x; 
var ny = ey - Drag.obj.lastMouseY + y; 
root.style.left = nx + "px"; 
root.style.top = ny + "px"; 
Drag.obj.root.onDrag(nx, ny); 
Drag.obj.lastMouseX = ex; 
Drag.obj.lastMouseY = ey; 
}, 
end: function (e) { 
var x = Drag.obj.root.style.left ? parseInt(Drag.obj.root.style.left) : 0; 
var y = Drag.obj.root.style.top ? parseInt(Drag.obj.root.style.top) : 0; 
Drag.obj.root.onDragEnd(x, y); 
document.onmousemove = null; 
document.onmouseup = null; 
Drag.obj = null; 
}, 
fixEvent: function (e) { 
e.pageX = e.clientX + document.documentElement.scrollLeft; 
e.pageY = e.clientY + document.documentElement.scrollTop; 
return e; 
} 
}

上面init主要处理一些初如化工作,如记录onDragStart、onDrag、onDragEnd三个事件, handler为处理拖动事件的那个元素,root为被拖动的元素。
当在handler上点击后触发Drag.start方法,Drag.start主要为记录住鼠标相对整个页面的位置;给document注册onmouseup、onmousemove事件,及触发onDragStart事件。
Drag.drag方法也很简单,主要作用就是更新被搬移元素位置,同时记录住鼠标相对整个页面的位置。
Drag.end方法就更简单了,就是做一些收尾工作。

最后给大家附段使用的代码吧,祝大家学习愉快!

Drag.init({ 
handler: document.getElementById("handler"), 
root:document.getElementById("root"); 
}); 
<div id="root"> 
<h2 id="handler"></h2> 
</div>
Javascript 相关文章推荐
JavaScript中的isXX系列是否继续使用的分析
Apr 16 Javascript
19个很有用的 JavaScript库推荐
Jun 27 Javascript
原生javascript实现的分页插件pagenav
Aug 28 Javascript
Bootstrap开关(switch)控件学习笔记分享
May 30 Javascript
JavaScript轮播图简单制作方法
Feb 20 Javascript
详解VUE的状态控制与延时加载刷新
Mar 27 Javascript
Angular客户端请求Rest服务跨域问题的解决方法
Sep 19 Javascript
vue2.0+koa2+mongodb实现注册登录
Apr 10 Javascript
VeeValidate在vue项目里表单校验应用案例
May 09 Javascript
微信小程序实现tab页面切换功能
Jul 13 Javascript
在element-ui的select下拉框加上滚动加载
Apr 18 Javascript
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
Apr 29 Javascript
教您去掉ie网页加载进度条的方法
Dec 09 #Javascript
javascript 折半查找字符在数组中的位置(有序列表)
Dec 09 #Javascript
基于jQuery的一个扩展form序列化到json对象
Dec 09 #Javascript
来自国外的页面JavaScript文件优化
Dec 08 #Javascript
js 替换功能函数,用正则表达式解决,js的全部替换
Dec 08 #Javascript
javascript中callee与caller的用法和应用场景
Dec 08 #Javascript
js下通过prototype扩展实现indexOf的代码
Dec 08 #Javascript
You might like
【星际争霸1】人族1v7家ZBath
2020/03/04 星际争霸
第十三节--对象串行化
2006/11/16 PHP
php 保留字列表
2012/10/04 PHP
PHP类的特性实例分析
2016/09/28 PHP
Zend Framework常用校验器详解
2016/12/09 PHP
微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解
2019/04/10 PHP
Apply an AutoFormat to an Excel Spreadsheet
2007/06/12 Javascript
JSQL SQLProxy 的 php 版本代码
2010/05/05 Javascript
Jquery+asp.net后台数据传到前台js进行解析的方法
2014/05/11 Javascript
判断日期是否能跨月查询的js代码
2014/07/25 Javascript
jquery中trigger()无法触发hover事件的解决方法
2015/05/07 Javascript
JavaScript基于原型链的继承
2016/06/22 Javascript
js实现自定义进度条效果
2017/03/15 Javascript
JavaScript内存泄漏的处理方式
2017/11/20 Javascript
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
2018/06/19 Javascript
在Angular中使用JWT认证方法示例
2018/09/10 Javascript
微信小程序实现上拉加载功能
2019/11/20 Javascript
JavaScript实现省份城市的三级联动
2020/02/11 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
2020/02/15 Javascript
[01:08:29]DOTA2-DPC中国联赛定级赛 RNG vs Aster BO3第一场 1月9日
2021/03/11 DOTA
python的几种开发工具介绍
2007/03/07 Python
Python中unittest用法实例
2014/09/25 Python
Python open()文件处理使用介绍
2014/11/30 Python
Python根据区号生成手机号码的方法
2015/07/08 Python
Python中的字典与成员运算符初步探究
2015/10/13 Python
pandas.DataFrame 根据条件新建列并赋值的方法
2018/04/08 Python
python自动化之Ansible的安装教程
2019/06/13 Python
python中的colorlog库使用详解
2019/07/05 Python
重构Python代码的六个实例
2020/11/25 Python
鱼油专家:Omegavia
2016/10/10 全球购物
几个Linux面试题笔试题
2012/12/01 面试题
青年文明号口号
2014/06/17 职场文书
医学生求职信
2014/07/01 职场文书
2015年司法局工作总结
2015/05/22 职场文书
Go缓冲channel和非缓冲channel的区别说明
2021/04/25 Golang
SQL Server中的游标介绍
2022/05/20 SQL Server