js完美的div拖拽实例代码


Posted in Javascript onJanuary 22, 2014
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>拖拽库</title>
<style type="text/css">
div,h2,p{margin:0;padding:0;}
body{font:14px/1.5 arial;}
#box{width:100px;height:100px;background:#fef4eb;padding:5px;margin:50px;border:1px solid #f60;}
#box .title{height:25px;background:#f60;}
#tool{margin-bottom:10px;}
</style>
<script type="text/javascript">
function Drag()
{
 //初始化
 this.initialize.apply(this, arguments)
}
Drag.prototype = {
 //初始化
 initialize : function (drag, options)
 {
  this.drag = this.$(drag);
  this._x = this._y = 0;
  this._moveDrag = this.bind(this, this.moveDrag);
  this._stopDrag = this.bind(this, this.stopDrag);  this.setOptions(options);
  this.handle = this.$(this.options.handle);
  this.maxContainer = this.$(this.options.maxContainer);
  this.maxTop = Math.max(this.maxContainer.clientHeight, this.maxContainer.scrollHeight) - this.drag.offsetHeight;
  this.maxLeft = Math.max(this.maxContainer.clientWidth, this.maxContainer.scrollWidth) - this.drag.offsetWidth;
  this.limit = this.options.limit;
  this.lockX = this.options.lockX;
  this.lockY = this.options.lockY;
  this.lock = this.options.lock;
  this.onStart = this.options.onStart;
  this.onMove = this.options.onMove;
  this.onStop = this.options.onStop;
  this.handle.style.cursor = "move";
  this.changeLayout();
  this.addHandler(this.handle, "mousedown", this.bind(this, this.startDrag))
 },
 changeLayout : function ()
 {
  this.drag.style.top = this.drag.offsetTop + "px";
  this.drag.style.left = this.drag.offsetLeft + "px";
  this.drag.style.position = "absolute";
  this.drag.style.margin = "0"
 },
 startDrag : function (event)
 {  
  var event = event || window.event;
  this._x = event.clientX - this.drag.offsetLeft;
  this._y = event.clientY - this.drag.offsetTop;
  this.addHandler(document, "mousemove", this._moveDrag);
  this.addHandler(document, "mouseup", this._stopDrag);
  event.preventDefault && event.preventDefault();
  this.handle.setCapture && this.handle.setCapture();
  this.onStart()
 },
 moveDrag : function (event)
 {
  var event = event || window.event;
  var iTop = event.clientY - this._y;
  var iLeft = event.clientX - this._x;
  if (this.lock) return;
  this.limit && (iTop < 0 && (iTop = 0), iLeft < 0 && (iLeft = 0), iTop > this.maxTop && (iTop = this.maxTop), iLeft > this.maxLeft && (iLeft = this.maxLeft));
  this.lockY || (this.drag.style.top = iTop + "px");
  this.lockX || (this.drag.style.left = iLeft + "px");
  event.preventDefault && event.preventDefault();
  this.onMove()
 },
 stopDrag : function ()
 {
  this.removeHandler(document, "mousemove", this._moveDrag);
  this.removeHandler(document, "mouseup", this._stopDrag);
  this.handle.releaseCapture && this.handle.releaseCapture();
  this.onStop()
 },
 //参数设置
 setOptions : function (options)
 {
  this.options =
  {
   handle:   this.drag, //事件对象
   limit:   true, //锁定范围
   lock:   false, //锁定位置
   lockX:   false, //锁定水平位置
   lockY:   false, //锁定垂直位置
   maxContainer: document.documentElement || document.body, //指定限制容器
   onStart:  function () {}, //开始时回调函数
   onMove:   function () {}, //拖拽时回调函数
   onStop:   function () {}  //停止时回调函数
  };
  for (var p in options) this.options[p] = options[p]
 },
 //获取id
 $ : function (id)
 {
  return typeof id === "string" ? document.getElementById(id) : id
 },
 //添加绑定事件
 addHandler : function (oElement, sEventType, fnHandler)
 {
  return oElement.addEventListener ? oElement.addEventListener(sEventType, fnHandler, false) : oElement.attachEvent("on" + sEventType, fnHandler)
 },
 //删除绑定事件
 removeHandler : function (oElement, sEventType, fnHandler)
 {
  return oElement.removeEventListener ? oElement.removeEventListener(sEventType, fnHandler, false) : oElement.detachEvent("on" + sEventType, fnHandler)
 },
 //绑定事件到对象
 bind : function (object, fnHandler)
 {
  return function ()
  {
   return fnHandler.apply(object, arguments) 
  }
 }
};

 
 
//应用
window.onload = function ()
{
 var oBox = document.getElementById("box"); 
 var oTitle = oBox.getElementsByTagName("h2")[0];
 var oSpan = document.getElementsByTagName("span")[0];
 var oDrag = new Drag(oBox, {handle:oTitle, limit:false});
 var aInput = document.getElementsByTagName("input");
 //锁定范围接口
 aInput[0].onclick = function ()
 {
  oDrag.limit = !oDrag.limit;
  this.value = oDrag.limit ? "取消锁定范围" : "锁定范围"
 };
 //水平锁定接口
 aInput[1].onclick = function ()
 {
  oDrag.lockX = !oDrag.lockX;
  this.value = oDrag.lockX ? "取消水平锁定" : "水平锁定"
 };
 //垂直锁定接口
 aInput[2].onclick = function ()
 {
  oDrag.lockY = !oDrag.lockY;
  this.value = oDrag.lockY ? "取消垂直锁定" : "垂直锁定"
 };
 //锁定位置接口
 aInput[3].onclick = function ()
 {
  oDrag.lock = !oDrag.lock;
  this.value = oDrag.lock ? "取消锁定位置" : "锁定位置"
 };
 //开始拖拽时方法
 oDrag.onStart = function ()
 {
  oSpan.innerHTML = "开始拖拽" 
 };
 //开始拖拽时方法
 oDrag.onMove = function ()
 {
  oSpan.innerHTML = "left:" + this.drag.offsetLeft + ", top:" + this.drag.offsetTop 
 };
 //开始拖拽时方法
 oDrag.onStop = function ()
 {
  oSpan.innerHTML = "结束拖拽" 
 };
};
</script>
</head>
<body>
<div id="tool">
 <input type="button" value="锁定范围" />
    <input type="button" value="水平锁定" />
    <input type="button" value="垂直锁定" />
    <input type="button" value="锁定位置" />
</div>
<p>拖放状态:<span>未开始</span></p>
<div id="box">
 <h2 class="title"></h2>
</div>
</body>
</html>
</td>
   </tr>
 </table>
Javascript 相关文章推荐
jQuery队列控制方法详解queue()/dequeue()/clearQueue()
Dec 02 Javascript
js添加table的行和列 具体实现方法
Jul 22 Javascript
javascript事件委托的用法及其好处简析
Apr 04 Javascript
javascript的几种写法总结
Sep 30 Javascript
详解vue2.0 transition 多个元素嵌套使用过渡
Jun 19 Javascript
JavaScript 获取元素在父节点中的下标(推荐)
Jun 28 Javascript
详解Chai.js断言库API中文文档
Jan 31 Javascript
JS/jQuery实现DIV延时几秒后消失或显示的方法
Feb 12 jQuery
node中的密码安全(加密)
Sep 17 Javascript
基于canvasJS在PHP中制作动态图表
May 30 Javascript
国内常用的js类库大全(CDN公共库)
Jun 24 Javascript
js实现简单的倒计时
Jan 28 Javascript
jquery中对于批量deferred的处理方法
Jan 22 #Javascript
jquery基础教程之deferred对象使用方法
Jan 22 #Javascript
jquery each的几种常用的使用方法示例
Jan 21 #Javascript
JavaScript在for循环中绑定事件解决事件参数不同的情况
Jan 20 #Javascript
javascript break指定标签打破多层循环示例
Jan 20 #Javascript
js点击出现悬浮窗效果不使用JQuery插件
Jan 20 #Javascript
javascript中直接引用Microsoft的COM生成Word
Jan 20 #Javascript
You might like
PHP不用递归实现无限分级的例子分享
2014/04/18 PHP
PHP中预定义的6种接口介绍
2015/05/12 PHP
PHP实现根据时间戳获取周几的方法
2016/02/26 PHP
摘自启点的main.js
2008/04/20 Javascript
JQuery for与each性能比较分析
2013/05/14 Javascript
javascript 通用loading动画效果实例代码
2014/01/14 Javascript
jQuery Mobile开发中日期插件Mobiscroll使用说明
2016/03/02 Javascript
原生javascript实现的ajax异步封装功能示例
2016/11/03 Javascript
jquery pagination分页插件使用详解(后台struts2)
2017/01/22 Javascript
jQuery扇形定时器插件pietimer使用方法详解
2017/07/18 jQuery
Node.Js中实现端口重用原理详解
2018/05/03 Javascript
深入浅析Vue.js计算属性和侦听器
2018/05/05 Javascript
微信小程序中时间戳和日期的相互转换问题
2018/07/09 Javascript
vue展示dicom文件医疗系统的实现代码
2018/08/27 Javascript
[02:28]DOTA2英雄基础教程 灰烬之灵
2013/12/19 DOTA
python备份文件的脚本
2008/08/11 Python
详解Python装饰器由浅入深
2016/12/09 Python
Python实现FTP文件传输的实例
2019/07/07 Python
TensorFlow 输出checkpoint 中的变量名与变量值方式
2020/02/11 Python
Python enumerate内置库用法解析
2020/02/24 Python
Python3通过chmod修改目录或文件权限的方法示例
2020/06/08 Python
Python Serial串口基本操作(收发数据)
2020/11/06 Python
英国标志性奢侈品牌:Burberry
2016/07/28 全球购物
英国著名药妆店:Superdrug
2021/02/13 全球购物
幼儿园家长会欢迎词
2014/01/09 职场文书
卫生系统先进事迹
2014/05/13 职场文书
社区健康教育工作方案
2014/06/03 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
新闻人物通讯稿
2014/10/09 职场文书
2014年销售助理工作总结
2014/12/01 职场文书
七年级上册语文教学计划
2015/01/22 职场文书
物业保洁员岗位职责
2015/02/13 职场文书
公司优秀员工推荐信
2015/03/24 职场文书
2015年大学生工作总结
2015/04/21 职场文书
党小组鉴定意见
2015/06/02 职场文书
Win11局域网共享权限在哪里设置? Win11高级共享的设置技巧
2022/04/05 数码科技