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 相关文章推荐
Extjs中的GridPanel隐藏列会显示在menuDisabled中解决方法
Jan 27 Javascript
基于jquery实现控制经纬度显示地图与卫星
May 20 Javascript
基于HTML+CSS+JS实现增加删除修改tab导航特效代码
Aug 05 Javascript
Vue.js 父子组件通讯开发实例
Sep 06 Javascript
JS双击变input框批量修改内容
Dec 12 Javascript
JavaScript自定义浏览器滚动条兼容IE、 火狐和chrome
Jan 05 Javascript
Javascript面试经典套路reduce函数查重
Mar 23 Javascript
微信小程序 刷新上拉下拉不会断详细介绍
May 11 Javascript
Vue resource中的GET与POST请求的实例代码
Jul 21 Javascript
Vue axios全局拦截 get请求、post请求、配置请求的实例代码
Nov 28 Javascript
Node.js实现用户评论社区功能(体验前后端开发的乐趣)
May 09 Javascript
详解nginx配置vue h5 history去除#号
Nov 09 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错误Cannot use object of type stdClass as array in错误的解决办法
2014/06/12 PHP
php实现高效获取图片尺寸的方法
2014/12/12 PHP
php中stdClass的用法分析
2015/02/27 PHP
php使用GD实现颜色渐变实例
2015/06/02 PHP
总结的一些PHP开发中的tips(必看篇)
2017/03/24 PHP
php file_get_contents取文件中数组元素的方法
2017/04/01 PHP
PHP使用观察者模式处理异常信息的方法详解
2019/09/24 PHP
在thinkphp5.0路径中实现去除index.php的方式
2019/10/16 PHP
Javascript玩转继承(三)
2014/05/08 Javascript
JavaScript实现当网页加载完成后执行指定函数的方法
2015/03/21 Javascript
angularjs学习笔记之三大模块(modal,controller,view)
2015/09/26 Javascript
微信小程序 数据绑定详解及实例
2016/10/25 Javascript
详解vue渲染从后台获取的json数据
2017/07/06 Javascript
Js中async/await的执行顺序详解
2017/09/22 Javascript
NW.js 简介与使用方法
2018/02/01 Javascript
详解Node 定时器
2018/02/26 Javascript
JavaScript实现短暂提示框功能
2018/04/04 Javascript
Vue常用指令详解分析
2018/08/19 Javascript
Vue动画事件详解及过渡动画实例
2019/02/09 Javascript
微信小程序实现简易table表格
2020/06/19 Javascript
vue设计一个倒计时秒杀的组件详解
2019/04/06 Javascript
从零到一详聊创建Vue工程及遇到的常见问题
2019/04/25 Javascript
javascript导出csv文件(excel)的方法示例
2019/08/25 Javascript
vue点击自增和求和的实例代码
2019/11/06 Javascript
js通过循环多张图片实现动画效果
2019/12/19 Javascript
Windows系统下安装Python的SSH模块教程
2015/02/05 Python
Python判断变量是否为Json格式的字符串示例
2017/05/03 Python
python 通过xml获取测试节点和属性的实例
2018/03/31 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
python数据化运营的重要意义
2019/11/25 Python
Python socket服务常用操作代码实例
2020/06/22 Python
python和go语言的区别是什么
2020/07/20 Python
Rodd & Gunn澳大利亚官网:新西兰男装品牌
2018/09/25 全球购物
如何用Python来进行查询和替换一个文本字符串
2014/01/02 面试题
党员大会主持词
2014/04/02 职场文书
go设置多个GOPATH的方式
2021/05/05 Golang