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 相关文章推荐
Javascript实现仿WebQQ界面的“浮云”兼容 IE7以上版本及FF
Apr 27 Javascript
40个有创意的jQuery图片、内容滑动及弹出插件收藏集之一
Dec 31 Javascript
JS 加入收藏夹的代码(主流浏览器通用)
May 13 Javascript
js简单实现根据身份证号码识别性别年龄生日
Nov 29 Javascript
JS脚本defer的作用示例介绍
Jan 02 Javascript
用Move.js配合创建CSS3动画的入门指引
Jul 22 Javascript
用vue构建多页面应用的示例代码
Sep 20 Javascript
jQuery实现移动端图片上传预览组件的方法分析
May 01 jQuery
JavaScript实现手机号码 3-4-4格式并控制新增和删除时光标的位置
Jun 02 Javascript
js模拟实现百度搜索
Jun 28 Javascript
vue的hash值原理也是table切换实例代码
Dec 14 Vue.js
微信小程序onShareTimeline()实现分享朋友圈
Jan 07 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
Session的工作方式
2006/10/09 PHP
深入理解PHP原理之异常机制
2010/08/21 PHP
php遍历数组的方法分享
2012/03/22 PHP
PHP编程中的常见漏洞和代码实例
2014/08/06 PHP
PHP将HTML转换成文本的实现代码
2015/01/21 PHP
PHP连接SQLServer2005的方法
2015/01/27 PHP
js调用后台servlet方法实例
2013/06/09 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
javascript实现百度地图鼠标滑动事件显示、隐藏
2015/04/02 Javascript
javascript基础知识分享之类与函数化
2016/02/13 Javascript
jquery radio的取值_radio的选中_radio的重置方法
2016/09/20 Javascript
浅谈js算法和流程控制
2016/12/29 Javascript
jquery仿ps颜色拾取功能
2017/03/08 Javascript
微信小程序dom操作的替代思路实例分析
2018/12/06 Javascript
使用express来代理服务的方法
2019/06/21 Javascript
[59:48]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第一场 1月26日
2021/03/11 DOTA
Python操作sqlite3快速、安全插入数据(防注入)的实例
2014/04/26 Python
python实现冒泡排序算法的两种方法
2018/03/10 Python
python+opencv实现霍夫变换检测直线
2020/10/23 Python
python引用(import)某个模块提示没找到对应模块的解决方法
2019/01/19 Python
python 读取文件并把矩阵转成numpy的两种方法
2019/02/12 Python
Django的Modelforms用法简介
2019/07/27 Python
Atom Python 配置Python3 解释器的方法
2019/08/28 Python
Python3.7 读取 mp3 音频文件生成波形图效果
2019/11/05 Python
如何基于Python Matplotlib实现网格动画
2020/07/20 Python
基于python实现复制文件并重命名
2020/09/16 Python
公关关系专员的自我评价分享
2013/11/20 职场文书
材料会计岗位职责
2014/03/06 职场文书
幼儿园教师自我鉴定
2014/03/20 职场文书
信息与计算机科学职业规划范文:成为一艘有方向的船
2014/09/11 职场文书
个人学习党的群众路线教育实践活动心得体会
2014/11/05 职场文书
房产公证书样本
2015/01/23 职场文书
2016年教师政治思想表现评语
2015/12/02 职场文书
Django+Celery实现定时任务的示例
2021/06/23 Python
vue实现拖拽交换位置
2022/04/07 Vue.js
TaiShan 200服务器安装Ubuntu 18.04的图文教程
2022/06/28 Servers