JavaScript实现的多种鼠标拖放效果


Posted in Javascript onNovember 03, 2015

本文实例讲述了JavaScript实现的多种鼠标拖放效果。分享给大家供大家参考,具体如下:

这是一款JavaScript鼠标拖放效果代码,通过本示例了解触发对象,设置范围限制,指定容器大小水平及垂直锁定,还包括获取和释放焦点等。

运行效果截图如下:

JavaScript实现的多种鼠标拖放效果

在线演示地址如下:

具体代码如下:

<!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=gb2312" />
<title>拖放效果</title>
</head>
<body>
<script> 
var isIE = (document.all) ? true : false;
var $ = function (id) {
 return "string" == typeof id ? document.getElementById(id) : id;
};
var Class = {
 create: function() {
  return function() { this.initialize.apply(this, arguments); }
 }
}
var Extend = function(destination, source) {
 for (var property in source) {
  destination[property] = source[property];
 }
}
var Bind = function(object, fun) {
 return function() {
  return fun.apply(object, arguments);
 }
}
var BindAsEventListener = function(object, fun) {
 return function(event) {
  return fun.call(object, (event || window.event));
 }
}
var CurrentStyle = function(element){
 return element.currentStyle || document.defaultView.getComputedStyle(element, null);
}
function addEventHandler(oTarget, sEventType, fnHandler) {
 if (oTarget.addEventListener) {
  oTarget.addEventListener(sEventType, fnHandler, false);
 } else if (oTarget.attachEvent) {
  oTarget.attachEvent("on" + sEventType, fnHandler);
 } else {
  oTarget["on" + sEventType] = fnHandler;
 }
};
function removeEventHandler(oTarget, sEventType, fnHandler) {
 if (oTarget.removeEventListener) {
 oTarget.removeEventListener(sEventType, fnHandler, false);
 } else if (oTarget.detachEvent) {
 oTarget.detachEvent("on" + sEventType, fnHandler);
 } else { 
 oTarget["on" + sEventType] = null;
 }
};
//拖放程序
var Drag = Class.create();
Drag.prototype = {
//拖放对象
 initialize: function(drag, options) {
 this.Drag = $(drag);//拖放对象
 this._x = this._y = 0;//记录鼠标相对拖放对象的位置
 this._marginLeft = this._marginTop = 0;//记录margin
 //事件对象(用于绑定移除事件)
 this._fM = BindAsEventListener(this, this.Move);
 this._fS = Bind(this, this.Stop);
 this.SetOptions(options);
 this.Limit = !!this.options.Limit;
 this.mxLeft = parseInt(this.options.mxLeft);
 this.mxRight = parseInt(this.options.mxRight);
 this.mxTop = parseInt(this.options.mxTop);
 this.mxBottom = parseInt(this.options.mxBottom);
 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 = $(this.options.Handle) || this.Drag;
 this._mxContainer = $(this.options.mxContainer) || null;
 this.Drag.style.position = "absolute";
 //透明
 if(isIE && !!this.options.Transparent){
  //填充拖放对象
  with(this._Handle.appendChild(document.createElement("div")).style){
   width = height = "100%"; backgroundColor = "#fff"; filter = "alpha(opacity:0)";
  }
 }
 //修正范围
 this.Repair();
 addEventHandler(this._Handle, "mousedown", BindAsEventListener(this, this.Start));
 },
 //设置默认属性
 SetOptions: function(options) {
 this.options = {//默认值
  Handle:   "",//设置触发对象(不设置则使用拖放对象)
  Limit:   false,//是否设置范围限制(为true时下面参数有用,可以是负数)
  mxLeft:   0,//左边限制
  mxRight:  9999,//右边限制
  mxTop:   0,//上边限制
  mxBottom:  9999,//下边限制
  mxContainer: "",//指定限制在容器内
  LockX:   false,//是否锁定水平方向拖放
  LockY:   false,//是否锁定垂直方向拖放
  Lock:   false,//是否锁定
  Transparent: false,//是否透明
  onStart:  function(){},//开始移动时执行
  onMove:   function(){},//移动时执行
  onStop:   function(){}//结束移动时执行
 };
 Extend(this.options, options || {});
 },
 //准备拖动
 Start: function(oEvent) {
 if(this.Lock){ return; }
 this.Repair();
 //记录鼠标相对拖放对象的位置
 this._x = oEvent.clientX - this.Drag.offsetLeft;
 this._y = oEvent.clientY - this.Drag.offsetTop;
 //记录margin
 this._marginLeft = parseInt(CurrentStyle(this.Drag).marginLeft) || 0;
 this._marginTop = parseInt(CurrentStyle(this.Drag).marginTop) || 0;
 //mousemove时移动 mouseup时停止
 addEventHandler(document, "mousemove", this._fM);
 addEventHandler(document, "mouseup", this._fS);
 if(isIE){
  //焦点丢失
  addEventHandler(this._Handle, "losecapture", this._fS);
  //设置鼠标捕获
  this._Handle.setCapture();
 }else{
  //焦点丢失
  addEventHandler(window, "blur", this._fS);
  //阻止默认动作
  oEvent.preventDefault();
 };
 //附加程序
 this.onStart();
 },
 //修正范围
 Repair: function() {
 if(this.Limit){
  //修正错误范围参数
  this.mxRight = Math.max(this.mxRight, this.mxLeft + this.Drag.offsetWidth);
  this.mxBottom = Math.max(this.mxBottom, this.mxTop + this.Drag.offsetHeight);
  //如果有容器必须设置position为relative来相对定位,并在获取offset之前设置
  !this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || (this._mxContainer.style.position = "relative");
 }
 },
 //拖动
 Move: function(oEvent) {
 //判断是否锁定
 if(this.Lock){ this.Stop(); return; };
 //清除选择
 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
 //设置移动参数
 var iLeft = oEvent.clientX - this._x, iTop = oEvent.clientY - this._y;
 //设置范围限制
 if(this.Limit){
  //设置范围参数
  var mxLeft = this.mxLeft, mxRight = this.mxRight, mxTop = this.mxTop, mxBottom = this.mxBottom;
  //如果设置了容器,再修正范围参数
  if(!!this._mxContainer){
   mxLeft = Math.max(mxLeft, 0);
   mxTop = Math.max(mxTop, 0);
   mxRight = Math.min(mxRight, this._mxContainer.clientWidth);
   mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);
  };
  //修正移动参数
  iLeft = Math.max(Math.min(iLeft, mxRight - this.Drag.offsetWidth), mxLeft);
  iTop = Math.max(Math.min(iTop, mxBottom - this.Drag.offsetHeight), mxTop);
 }
 //设置位置,并修正margin
 if(!this.LockX){ this.Drag.style.left = iLeft - this._marginLeft + "px"; }
 if(!this.LockY){ this.Drag.style.top = iTop - this._marginTop + "px"; }
 //附加程序
 this.onMove();
 },
 //停止拖动
 Stop: function() {
 //移除事件
 removeEventHandler(document, "mousemove", this._fM);
 removeEventHandler(document, "mouseup", this._fS);
 if(isIE){
  removeEventHandler(this._Handle, "losecapture", this._fS);
  this._Handle.releaseCapture();
 }else{
  removeEventHandler(window, "blur", this._fS);
 };
 //附加程序
 this.onStop();
 }
};
</script>
<style> 
#idContainer{ border:10px solid #990000; width:600px; height:300px;}
#idDrag{ border:5px solid #C4E3FD; background:#C4E3FD; width:50px; height:50px; top:50px; left:50px;}
#idHandle{cursor:move; height:25px; background:#0000FF; overflow:hidden;}
</style>
<div id="idContainer">
<div id="idDrag"><div id="idHandle"></div></div>
</div>
<input id="idReset" type="button" value="复位" />
<input id="idLock" type="button" value="锁定" />
<input id="idLockX" type="button" value="锁定水平" />
<input id="idLockY" type="button" value="锁定垂直" />
<input id="idLimit" type="button" value="范围锁定" />
<input id="idLimitOff" type="button" value="取消范围锁定" />
<br />拖放状态:<span id="idShow">未开始</span>
<script> 
var drag = new Drag("idDrag", { mxContainer: "idContainer", Handle: "idHandle", Limit: true,
 onStart: function(){ $("idShow").innerHTML = "开始拖放"; },
 onMove: function(){ $("idShow").innerHTML = "left:"+this.Drag.offsetLeft+";top:"+this.Drag.offsetTop; },
 onStop: function(){ $("idShow").innerHTML = "结束拖放"; }
});
$("idReset").onclick = function(){
 drag.Limit = true;
 drag.mxLeft = drag.mxTop = 0;
 drag.mxRight = drag.mxBottom = 9999;
 drag.LockX = drag.LockY = drag.Lock = false;
}
$("idLock").onclick = function(){ drag.Lock = true; }
$("idLockX").onclick = function(){ drag.LockX = true; }
$("idLockY").onclick = function(){ drag.LockY = true; }
$("idLimit").onclick = function(){  drag.mxRight = drag.mxBottom = 200;drag.Limit = true; }
$("idLimitOff").onclick = function(){ drag.Limit = false; }
</script>
</body>
</html>

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
控制打印时页眉角的代码
Feb 08 Javascript
通过继承IHttpHandle实现JS插件的组织与管理
Jul 13 Javascript
浅析LigerUi开发中谨慎载入common.css文件
Jul 09 Javascript
JS实现将人民币金额转换为大写的示例代码
Feb 13 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
Jun 15 Javascript
jQuery 动态云标签插件
Nov 11 Javascript
利用原生JS自动生成文章标题树的实例
Aug 22 Javascript
BootStrap入门教程(二)之固定的内置样式
Sep 19 Javascript
@angular前端项目代码优化之构建Api Tree的方法
Dec 24 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
Apr 23 jQuery
js在HTML的三种引用方式详解
Aug 29 Javascript
vue Cli 环境删除与重装教程 - 版本文档
Sep 11 Javascript
JavaScript实现的Tween算法及缓冲特效实例代码
Nov 03 #Javascript
jQuery实现Email邮箱地址自动补全功能代码
Nov 03 #Javascript
jQuery实现仿QQ头像闪烁效果的文字闪动提示代码
Nov 03 #Javascript
基于JavaScript怎么实现让歌词滚动播放
Nov 03 #Javascript
ECMA5数组的新增方法有哪些及forEach()模仿实现
Nov 03 #Javascript
Javascript设计模式理论与编程实战之简单工厂模式
Nov 03 #Javascript
JS实现网页标题随机显示名人名言的方法
Nov 03 #Javascript
You might like
PHP中str_replace函数使用小结
2008/10/11 PHP
php实现短信发送代码
2015/07/05 PHP
详解PHP序列化和反序列化原理
2018/01/15 PHP
用jQuery技术实现Tab页界面之二
2009/09/21 Javascript
jquery 获取标签名(tagName)示例代码
2013/07/11 Javascript
javascript跨浏览器的属性判断方法
2014/03/16 Javascript
JsRender for object语法简介
2014/10/31 Javascript
AngularJs解决跨域问题案例详解(简单方法)
2016/05/19 Javascript
详谈Angular 2+ 的表单(一)之模板驱动型表单
2017/04/25 Javascript
JS操作时间 - UNIX时间戳的简单介绍(必看篇)
2017/08/16 Javascript
Js中使用正则表达式验证输入是否有特殊字符
2018/09/07 Javascript
基于js Canvas实现二次贝塞尔曲线
2018/12/25 Javascript
python实现数通设备tftp备份配置文件示例
2014/04/02 Python
Python中的exec、eval使用实例
2014/09/23 Python
python实现写数字文件名的递增保存文件方法
2018/10/25 Python
Python实现直方图均衡基本原理解析
2019/08/08 Python
python处理自动化任务之同时批量修改word里面的内容的方法
2019/08/23 Python
python实现简易学生信息管理系统
2020/04/05 Python
Python ORM编程基础示例
2020/02/02 Python
解决Jupyter无法导入已安装的 module问题
2020/04/17 Python
python实现按键精灵找色点击功能教程,使用pywin32和Pillow库
2020/06/04 Python
PyQt5-QDateEdit的简单使用操作
2020/07/12 Python
详解python tcp编程
2020/08/24 Python
CSS3关于z-index不生效问题的解决
2020/02/19 HTML / CSS
详解css3中dispaly的Grid布局与Flex布局
2020/09/11 HTML / CSS
原生 JS+CSS+HTML 实现时序图的方法
2019/07/31 HTML / CSS
使用layui实现左侧菜单栏及动态操作tab项的方法
2020/11/10 HTML / CSS
美国最大的农村生活方式零售店:Tractor Supply Company(TSC)
2017/05/15 全球购物
PHP如何设置和取得Cookie值
2015/06/30 面试题
教师工作总结范文2014
2014/11/10 职场文书
团结友爱主题班会
2015/08/13 职场文书
观看《筑梦中国》纪录片心得体会
2016/01/18 职场文书
幼儿园大班教师评语
2019/06/21 职场文书
人事部:年度述职报告范文
2019/07/12 职场文书
go语言中切片与内存复制 memcpy 的实现操作
2021/04/27 Golang
pytorch 运行一段时间后出现GPU OOM的问题
2021/06/02 Python