一起来写段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实现划词标记+划词搜索功能
Mar 06 Javascript
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
Dec 03 Javascript
jquery清空textarea等输入框实现代码
Apr 22 Javascript
js用正则表达式来验证表单(比较齐全的资源)
Nov 17 Javascript
Javascript字符串对象的常用方法简明版
Jun 26 Javascript
AngularJS内置指令
Feb 04 Javascript
JavaScript中的Math.LN2属性用法详解
Jun 12 Javascript
Backbone View 之间通信的三种方式
Aug 09 Javascript
Vue原理剖析 实现双向绑定MVVM
May 03 Javascript
MvcPager分页控件 适用于Bootstrap
Jun 03 Javascript
vue实现手机端省市区区域选择
Sep 27 Javascript
vue跳转页面的几种方法(推荐)
Mar 26 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仿discuz分页效果代码
2008/10/02 PHP
php实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
PHP读取txt文件的内容并赋值给数组的代码
2011/11/03 PHP
网页里控制图片大小的相关代码
2006/06/25 Javascript
接收键盘指令的脚本
2006/06/26 Javascript
键盘控制事件应用教程大全
2006/11/24 Javascript
js中判断Object、Array、Function等引用类型对象是否相等
2012/08/29 Javascript
js获取元素相对窗口位置的实现代码
2014/09/28 Javascript
JavaScript比较两个对象是否相等的方法
2015/02/06 Javascript
AngularJS学习笔记之基本指令(init、repeat)
2015/06/16 Javascript
jQuery拖动元素并对元素进行重新排序
2015/12/30 Javascript
js改变css样式的三种方法推荐
2016/06/28 Javascript
浅谈js的解析顺序 作用域 严格模式
2017/10/23 Javascript
pace.js和NProgress.js两个加载进度插件的一点小总结
2018/01/31 Javascript
angular项目中bootstrap-datetimepicker时间插件的使用示例
2018/03/15 Javascript
详解angular如何调用HTML字符串的方法
2018/06/30 Javascript
webpack4简单入门实例
2018/09/06 Javascript
JavaScript链式调用原理与实现方法详解
2020/05/16 Javascript
Python re模块介绍
2014/11/30 Python
python3简单实现微信爬虫
2015/04/09 Python
Python标准库之itertools库的使用方法
2017/09/07 Python
Pycharm 字体大小调整设置的方法实现
2019/09/27 Python
python中的subprocess.Popen()使用详解
2019/12/25 Python
python接入支付宝的实例操作
2020/07/20 Python
详解python中的lambda与sorted函数
2020/09/04 Python
如何使用python自带IDLE的几种方法
2020/10/10 Python
新加坡网上化妆品店:Best Buy World
2018/05/18 全球购物
财务会计专业毕业生自荐信
2013/10/02 职场文书
求职信标题怎么写
2014/05/26 职场文书
组工干部演讲稿
2014/09/02 职场文书
会议简讯范文
2015/07/20 职场文书
超市店长竞聘书
2015/09/15 职场文书
职场领导同事生日简短祝福语
2019/08/06 职场文书
解决Vue+SpringBoot+Shiro跨域问题
2021/06/09 Vue.js
django中websocket的具体使用
2022/01/22 Python
利用uni-app生成微信小程序的踩坑记录
2022/04/05 Javascript