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 相关文章推荐
页面装载js及性能分析方法介绍
Mar 21 Javascript
jQuery过滤HTML标签并高亮显示关键字的方法
Aug 07 Javascript
js图片跟随鼠标移动代码
Nov 26 Javascript
JS组件Bootstrap Select2使用方法详解
Apr 17 Javascript
Javascript的表单验证长度
Mar 16 Javascript
Vue.js学习示例分享
Feb 05 Javascript
js实现3d悬浮效果
Feb 16 Javascript
jquery实现的table排序功能示例
Mar 10 Javascript
vue动态路由实现多级嵌套面包屑的思路与方法
Aug 16 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
Nov 02 Javascript
Vue单页面应用保证F5强刷不清空数据的解决方案
Jan 31 Javascript
详解Vscode中使用Eslint终极配置大全
Nov 08 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正则校验用户名介绍
2008/07/19 PHP
sql注入与转义的php函数代码
2013/06/17 PHP
dedecms函数分享之获取某一栏目所有子栏目
2014/05/19 PHP
JavaScript 学习小结(适合新手参考)
2009/07/30 Javascript
解析js中获得父窗口链接getParent方法以及各种打开窗口的方法
2013/06/19 Javascript
js和jquery如何获取图片真实的宽度和高度
2014/09/28 Javascript
node.js中的http.response.addTrailers方法使用说明
2014/12/14 Javascript
JS+CSS模拟可以无刷新显示内容的留言板实例
2015/03/03 Javascript
JS日期格式化之javascript Date format
2015/10/01 Javascript
Bootstrap实现下拉菜单效果
2016/04/29 Javascript
关于function类中定义变量this的简单说明
2016/05/28 Javascript
Angular的Bootstrap(引导)和Compiler(编译)机制
2016/06/20 Javascript
详解用vue.js和laravel实现微信支付
2017/06/23 Javascript
详解在Vue中有条件地使用CSS类
2017/09/30 Javascript
javascript实现数字配对游戏的实例讲解
2017/12/14 Javascript
layui点击按钮页面会自动刷新的解决方案
2019/10/25 Javascript
Vue自定义组件双向绑定实现原理及方法详解
2020/09/03 Javascript
Vue如何循环提取对象数组中的值
2020/11/18 Vue.js
基于Vue2实现移动端图片上传、压缩、拖拽排序、拖拽删除功能
2021/01/05 Vue.js
python 线程的暂停, 恢复, 退出详解及实例
2016/12/06 Python
python strip() 函数和 split() 函数的详解及实例
2017/02/03 Python
使用Python对Excel进行读写操作
2017/03/30 Python
Python代码太长换行的实现
2019/07/05 Python
解决pycharm最左侧Tool Buttons显示不全的问题
2019/12/17 Python
tensorflow 实现自定义梯度反向传播代码
2020/02/10 Python
解决Jupyter notebook更换主题工具栏被隐藏及添加目录生成插件问题
2020/04/20 Python
Python根据URL地址下载文件并保存至对应目录的实现
2020/11/15 Python
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
2017/01/05 HTML / CSS
加拿大时尚潮流大码女装购物网站:Addition Elle
2018/04/02 全球购物
护理职业生涯规划书
2014/01/24 职场文书
金融管理应届生求职信
2014/02/20 职场文书
《分一分》教学反思
2014/04/13 职场文书
电子商务专业自荐信
2014/06/02 职场文书
KTV门卫岗位职责
2014/10/09 职场文书
社区党支部承诺书
2015/04/29 职场文书
建筑工程催款函
2015/06/24 职场文书