一起来写段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 相关文章推荐
解决AJAX中跨域访问出现'没有权限'的错误
Aug 20 Javascript
Javascript 同时提交多个Web表单的方法
Feb 19 Javascript
Array.prototype 的泛型应用分析
Apr 30 Javascript
jQuery窗口、文档、网页各种高度的精确理解
Jul 02 Javascript
使用jquery 简单实现下拉菜单
Jan 14 Javascript
原生js实现图片层叠轮播切换效果
Feb 02 Javascript
javascript原型继承工作原理和实例详解
Apr 07 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
Nov 06 Javascript
angularJs中datatable实现代码
Jun 03 Javascript
jsonp跨域请求详解
Jul 13 Javascript
inner join 内联与left join 左联的实例代码
Sep 18 Javascript
Vue 通过自定义指令回顾v-内置指令(小结)
Sep 03 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
php session 检测和注销
2009/03/16 PHP
php使用正则表达式提取字符串中尖括号、小括号、中括号、大括号中的字符串
2020/04/05 PHP
Zend Framework教程之Loader以及PluginLoader用法详解
2016/03/09 PHP
常用PHP封装分页工具类
2017/01/14 PHP
Python中使用django form表单验证的方法
2017/01/16 PHP
php登录超时检测功能实例详解
2017/03/21 PHP
ThinkPHP实现转换数据库查询结果数据到对应类型的方法
2017/11/16 PHP
laravel实现查询最后执行的一条sql语句的方法
2019/10/09 PHP
PHP http请求超时问题解决方案
2020/11/13 PHP
javascript中style.left和offsetLeft的用法说明
2014/03/07 Javascript
简单谈谈node.js 版本控制 nvm和 n
2015/10/15 Javascript
jQuery+PHP+MySQL二级联动下拉菜单实例讲解
2015/10/27 Javascript
Javascript操作表单实例讲解(下)
2016/06/20 Javascript
Javascript中字符串replace方法的第二个参数探究
2016/12/05 Javascript
纯原生js实现贪吃蛇游戏
2020/04/16 Javascript
使用jQuery实现页面定时弹出广告效果
2017/08/24 jQuery
浅谈React组件之性能优化
2018/03/02 Javascript
微信小程序实现运动步数排行功能(可删除)
2018/07/05 Javascript
cdn模式下vue的基本用法详解
2018/10/07 Javascript
vue 中this.$set 动态绑定数据的案例讲解
2021/01/29 Vue.js
Python使用Supervisor来管理进程的方法
2015/05/28 Python
Django框架下在视图中使用模版的方法
2015/07/16 Python
python多进程下实现日志记录按时间分割
2019/07/22 Python
Python Django Vue 项目创建过程详解
2019/07/29 Python
Python通过TensorFLow进行线性模型训练原理与实现方法详解
2020/01/15 Python
python中pyqtgraph知识点总结
2021/01/26 Python
Craghoppers德国官网:户外和旅行服装
2020/02/14 全球购物
社区优秀志愿者材料
2014/02/02 职场文书
广告创意求职信
2014/03/17 职场文书
军人离婚协议书样本
2014/10/21 职场文书
银行员工考核评语
2014/12/31 职场文书
语文教师个人工作总结
2015/02/06 职场文书
求职简历自我评价怎么写
2015/03/10 职场文书
雨雪天气温馨提示
2015/07/15 职场文书
2016年第32个教师节红领巾广播稿
2015/12/18 职场文书
AudioContext 实现音频可视化(web技术分享)
2022/02/24 Javascript