JQuery UI的拖拽功能实现方法小结


Posted in Javascript onMarch 14, 2012

JQuery UI提供的API极大简化了拖拽功能的开发。只需要分别在拖拽源(source)和目标(target)上调用draggable和droppable两个函数即可。

拖拽原理
首先要明确几个概念。

ource:拖拽源,要拖动的元素。

taerget:拖放目标,能够放入source的容器。
拖拽的动作分解如下:

1. drag start:在拖拽源(source)上按下鼠标并开始移动

2. drag move: 移动过程中

3. drag enter: 移动进入目标(target)容器

4. drag leave: 移出目标(target)容器

5. drop: 在目标(target)容器上释放鼠标

6. drag end: 结束
在html5之前,页面元素不直接支持拖拽事件。所以都是通过监听鼠标事件并记录拖拽状态的方式来实现拖拽功能。

最简单的例子
最简单的拖拽是不改变元素所在的容器,而只改变其位置。例子如下:

<html> 
<head></head> 
<body> 
<div id="container"> 
<div id="dragsource"> 
<p>拽我!</p> 
</div> 
</div><!-- End container --> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$( "#dragsource" ).draggable(); 
}) 
</script> 
</body> 
</html>

拖动到另一个容器
更常见的场景是将元素拖动到另一个容器中。这就需要在drop目标(target)容器上应用droppable函数。让我们在上一个例子的基础上,增加一个div作为容器,并应用droppable函数:
<html> 
<head></head> 
<body> 
<div id="container"> 
<div id="dragsource"> 
<p>拽我!</p> 
</div> 
</div><!-- End container --> <div id="droppalbe" style="width: 300px;height:300px;background-color:gray"> 
<p>Drop here</p> 
</div> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$( "#dragsource" ).draggable(); 
$( "#droppable" ).droppable(); 
}) 
</script> 
</body> 
</html>

事件监听和回显(Feedback)
运行上一个例子,你可能会产生疑惑,真的放到目标容器上了吗?用户也会产生同样的疑惑。所以,可以监听拖动过程中发生的一些事件,并用可见的方式让用户知道。这就叫做回显(Feedback)。

对于源(source),可以监听的事件包括:

create: 在source上应用draggable函数时触发

start:开始拖动时触发

drap:拖动过程中触发

stop:释放时触发
对于目标(target),可以监听的事件包括:

create: 在target上应用droppable函数时触发

activate:如果当前拖动的source可以drop到本target,则触发

deactivate:如果可以drop到本target的拖拽停止,则触发

over:source被拖动到target上面

out:source被拖动离开target

drop:source被释放到target
事件处理函数都是通过draggable和droppable函数的参数传递,在这些事件处理函数中就可以进行Feedback。看一下实际的例子:

<html> 
<head> </head> 
<body> 
<div id="dragsource"> 
<p id="targetMsg">:-|</p> 
</div> 
<div id="droppable" style="background-color:gray;height:300"> 
<p>Can drop! </p> 
</div> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$( "#dragsource" ).draggable({ 
start: function(event,ui) { 
$(this).find("p").html(":-S"); 
}, 
stop:function(event,ui){ 
$(this).find("p").html(":-|"); 
} 
}); 
$( "#droppable" ).droppable({ 
activate: function(event,ui) { 
$(this).find("p").html( "Drop here !" ); 
}, 
over: function(event,ui) { 
$( this ).find( "p" ).html( "Oh, Yeah!" ); 
}, 
out: function(event,ui) { 
$( this ).find( "p" ).html( "Don't leave me!" ); 
}, 
drop: function( event, ui ) { 
$( this ).find( "p" ).html( "I've got it!" ); 
} 
}); 
}) 
</script> 
</body> 
</html>

复制拖动
前面的例子都是移动元素,另一种常见的场景是复制拖动。比如visio中的从画板中拖动元素到画布。这是通过draggable函数的helper参数设定的。

helper可以指定为“original”, "clone",其中"original"是默认值,即拖动自身,而clone表示创建自身的一个克隆用于拖拽。helper还可以指定为函数,该函数返回一个自定义的DOM元素用于拖拽。
当不是拖动自身的时候,需要在target上指定drop事件函数,在该函数中将特定的元素添加到target容器上,否则drop的时候什么事情都不会发生。
简单复制的例子如下:

<html> 
<head></head> 
<body> <div id="dragsource"> 
<p>拽我!</p> 
</div> 
<div id="container" style="background-color:gray;height:300"> 
</div><!-- End container --> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$( "#dragsource" ).draggable({ 
helper:"clone" 
}); 
$("#container").droppable({ 
drop:function(event,ui){ 
$(this).append($("<p style='position:absolute;left:"+ 
ui.offset.left+";top:"+ui.offset.top+"'>clone</p>")); 
} 
}); 
}) 
</script> 
</body> 
</html>

拖动控制
到目前位置,所有的例子中都可以对source随意拖动。在实际应用中经常需要对拖动行为进行控制。下面给出几个例子。

拖动方向
默认拖动方向为x,y两个方向。通过draggable的axis参数可以限制只能水平或竖直拖动。如下:

<html> 
<head></head> 
<body> <div id="dragX"> 
<p>--</p> 
</div> 
<div id="dragY"> 
<p>|</p> 
</div> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$("#dragX").draggable({axis:"x"}); 
$("#dragY").draggable({axis:"y"}); 
}); 
</script> 
</body> 
</html>

拖动范围
除了方向之外,还可以通过containment参数约束拖动的范围。该参数接受Selector, Element, String, Array类型。其中String可以为parent,document,window,Array是指定一个矩形区域(regin)的四元数组:[x1,y1,x2,y2]。下面的例子分别指定了parent和regin作为范围限制:
<html> 
<head></head> 
<body> 
<div id="container" style="background-color:gray;height:300"> 
<div id="draggable1" style="background-color:red;height:20;width:100"> 
<p>in parent</p> 
</div> <div id="draggable2" style="background-color:green;height:20;width:100"> 
<p>in regin</p> 
</div> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$("#draggable1" ).draggable({containment: "parent" }); 
$("#draggable2").draggable({containment: [20,20,300,200] }); 
}); 
</script> 
</body> 
</html>

拖动吸附
还可以在拖动的时候吸附到其他元素或网格。使用snap参数指定要吸附到的元素,使用grid参数指定吸附到网格,如下:
<html> 
<head> 
<style> 
.draggable {background-color:green; width: 90px; height: 80px; padding: 5px; float: left; margin: 0 10px 10px 0; font-size: .9em; } 
</style> 
</head> 
<body> 
<div id="container" style="background-color:gray;height:300"> 
<div id="draggable1" class="draggable"> 
<p>吸附到其他可拖拽元素</p> 
</div> <div id="draggable2" class="draggable"> 
<p>吸附到容器</p> 
</div> 
<div id="draggable3" class="draggable"> 
<p>吸附到网格(30x30)</p> 
</div> 
</div><!--container--> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$("#draggable1").draggable({ snap: true }); 
$("#draggable2").draggable({ snap: "#container"}); 
$("#draggable3").draggable({grid: [30,30]}); 
}); 
</script> 
</body> 
</html>

拖动把手(handle)
默认是整个元素都可以拖动,也可以指定元素的某个子元素作为拖动的handle,如:
<div id="draggable"> 
<p>handle</p> 
</div> 
…… 
<script> 
$("#draggable").draggable({handle:"p"}); 
</script>

Drop限制
默认的droppable指定元素能够接受所有的drop, 但是可以通过accept参数限定只能接受某些元素的drop。accept参数的类型为一个符合jquery selector的字符串。例如:
$(".selector").droppable({ accept: '.special' })
表示只接受具有special 样式的元素。

增强用户体验
前面是实现拖拽的功能,JQueryUI还有一些参数可以增强用户体验。比如,cursor参数可以指定鼠标指针的形状,cursorAt指定鼠标指针在source的相对位置,revert可以指定当drop失败时source“飘”回原来的位置。一个组合的例子如下:

<html> 
<head> 
<style> 
.draggable {background-color:green; width: 90px; height: 80px; padding: 5px; float: left; margin: 0 10px 10px 0; font-size: .9em; } 
.droppable { width: 300px; height: 300px; background-color:red} </style> 
</head> 
<body> 
<div id="draggable2" class="draggable"> 
<p>I revert when I'm not dropped</p> 
</div> 
<div id="droppable" class="droppable"> 
<p>Drop me here</p> 
</div> 
<script type="text/javascript" src="js/jquery-1.7.min.js"></script> 
<script type="text/javascript" src="js/jquery-ui-1.8.16.custom.min.js"></script> 
<script> 
$(function() { 
$( "#draggable2" ).draggable({ revert: "invalid",cursor: "move", cursorAt: { top: 56, left: 56 } }); 
$( "#droppable" ).droppable({ 
activeClass: "ui-state-hover", 
hoverClass: "ui-state-active", 
drop: function( event, ui ) { 
$( this ) 
.addClass( "ui-state-highlight" ) 
.find( "p" ) 
.html( "Dropped!" ); 
} 
}); 
}); 
</script> 
</body> 
</html>

小结
JQuery UI提供了强大的拖拽功能和良好的用户体验,同时又非常容易使用。本文介绍了常用的各种用法。更多的参数还可以参考官方网站的Draggable 和 Droppable 。
Javascript 相关文章推荐
jQuery 判断元素上是否绑定了事件
Oct 28 Javascript
Jquery下attr和removeAttr的使用方法
Dec 28 Javascript
用javascript作一个通用向导说明
Aug 30 Javascript
Jquery修改页面标题title其它JS失效的解决方法
Oct 31 Javascript
JavaScript中的普通函数与构造函数比较
Apr 07 Javascript
javascript学习指南之回调问题
Apr 23 Javascript
JavaScript学习笔记整理_用于模式匹配的String方法
Sep 19 Javascript
Bootstrap和Java分页实例第二篇
Dec 23 Javascript
javascript监听页面刷新和页面关闭事件方法详解
Jan 09 Javascript
详解微信小程序开发之——wx.showToast(OBJECT)的使用
Jan 18 Javascript
Vue移动端实现图片上传及超过1M压缩上传
Dec 23 Javascript
create-react-app开发常用配置教程
Jun 25 Javascript
10款非常有用的 Ajax 插件分享
Mar 14 #Javascript
node.js chat程序如何实现Ajax long-polling长链接刷新模式
Mar 13 #Javascript
Jquery弹出窗口插件 LeanModal的使用方法
Mar 10 #Javascript
解决3.01版的jquery.form.js中文乱码问题的解决方法
Mar 08 #Javascript
Node.js实战 建立简单的Web服务器
Mar 08 #Javascript
使用UglifyJS合并/压缩JavaScript的方法
Mar 07 #Javascript
Uglifyjs(JS代码优化工具)入门 安装使用
Apr 13 #Javascript
You might like
彻底杜绝PHP的session cookie错误
2009/08/09 PHP
关于PHP5 Session生命周期介绍
2010/03/02 PHP
PHP中strtotime函数使用方法详解
2011/11/27 PHP
解析PHP将对象转换成数组的方法(兼容多维数组类型)
2013/06/21 PHP
PHP生成唯一订单号的方法汇总
2015/04/16 PHP
PHP下SSL加密解密、验证、签名方法(很简单)
2020/06/28 PHP
解决微信授权回调页面域名只能设置一个的问题
2016/12/11 PHP
Laravel 5.4.36中session没有保存成功问题的解决
2018/02/19 PHP
在JQuery dialog里的服务器控件 事件失效问题
2010/12/08 Javascript
jQuery代码优化 事件委托篇
2011/11/01 Javascript
Js四则运算函数代码
2012/07/21 Javascript
js 操作符汇总
2014/11/08 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
AngularJS 视图详解及示例代码
2016/08/17 Javascript
jQuery简单创建节点的方法
2016/09/09 Javascript
js获取Get值的方法
2016/09/29 Javascript
node.js 利用流实现读写同步,边读边写的方法
2017/09/11 Javascript
详谈vue+webpack解决css引用图片打包后找不到资源文件的问题
2018/03/06 Javascript
vue通过点击事件读取音频文件的方法
2018/05/30 Javascript
vue.js实现格式化时间并每秒更新显示功能示例
2018/07/07 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
python 简易计算器程序,代码就几行
2009/08/29 Python
python 简单备份文件脚本v1.0的实例
2017/11/06 Python
Python与R语言的简要对比
2017/11/14 Python
Python中顺序表原理与实现方法详解
2019/12/03 Python
PyCharm+PyQt5+QtDesigner配置详解
2020/08/12 Python
德国化妆品和天然化妆品网上商店:kosmetikfuchs.de
2017/06/09 全球购物
泰海淘:泰国king Power王权免税集团旗下跨境海淘综合型电商
2020/07/26 全球购物
房地产销售大学生自我评价分享
2013/11/11 职场文书
大二学生学习个人自我评价
2014/01/19 职场文书
化妆师职业生涯规划书
2014/02/16 职场文书
《云房子》教学反思
2014/04/20 职场文书
2014年母亲节演讲稿范文
2014/05/07 职场文书
质监局领导班子对照检查材料思想汇报
2014/09/27 职场文书
Python MNIST手写体识别详解与试练
2021/11/07 Python
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js