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 相关文章推荐
Apply an AutoFormat to an Excel Spreadsheet
Jun 12 Javascript
强大的jquery插件jqeuryUI做网页对话框效果!简单
Apr 14 Javascript
jquery.Ajax()方法调用Asp.Net后台的方法解析
Feb 13 Javascript
使用window.prompt()实现弹出用户输入的对话框
Apr 13 Javascript
js编写当天简单日历效果【实现代码】
May 03 Javascript
ionic实现可滑动的tab选项卡切换效果
Apr 15 Javascript
js判断一个字符串是以某个字符串开头的简单实例
Dec 27 Javascript
JavaScript的级联函数用法简单示例【链式调用】
Mar 26 Javascript
JS左右无缝轮播功能完整实例
May 16 Javascript
Vue打包后访问静态资源路径问题
Nov 08 Javascript
Vue 打包体积优化方案小结
May 20 Javascript
vue router 动态路由清除方式
May 25 Vue.js
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
模仿OSO的论坛(三)
2006/10/09 PHP
php mysql索引问题
2008/06/07 PHP
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
2011/08/22 PHP
如何解决CI框架的Disallowed Key Characters错误提示
2013/07/05 PHP
一个显示效果非常不错的PHP错误、异常处理类
2014/03/21 PHP
Zend Framework实现多文件上传功能实例
2016/03/21 PHP
php使用curl伪造浏览器访问操作示例
2019/09/30 PHP
Javascript开发包大全整理
2006/12/22 Javascript
JS处理VBArray的函数使用说明
2008/05/11 Javascript
jQueryUI的Dialog的简单封装
2010/06/07 Javascript
jQuery创建自己的插件(自定义插件)的方法
2010/06/10 Javascript
jQuery fadeTo方法调整图片的透明度使用介绍
2013/05/06 Javascript
jQuery:delegate中select()不起作用的解决方法(实例讲解)
2014/01/26 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
2015/08/26 Javascript
js select实现省市区联动选择
2020/04/17 Javascript
JS类的定义与使用方法深入探索
2016/11/26 Javascript
基于openlayers4实现点的扩散效果
2020/08/17 Javascript
JS实现换肤功能的方法实例详解
2019/01/30 Javascript
浅谈监听单选框radio改变事件(和layui中单选按钮改变事件)
2019/09/10 Javascript
vue的路由映射问题及解决方案
2019/10/14 Javascript
js实现烟花特效
2020/03/02 Javascript
[06:48]DOTA2-DPC中国联赛2月26日Recap集锦
2021/03/11 DOTA
python检索特定内容的文本文件实例
2018/06/05 Python
PyQt5 QTable插入图片并动态更新的实例
2019/06/18 Python
基于python实现音乐播放器代码实例
2020/07/01 Python
Windows下PyCharm配置Anaconda环境(超详细教程)
2020/07/31 Python
python实现每天自动签到领积分的示例代码
2020/08/18 Python
Liu Jo西班牙官网:意大利服装品牌
2019/09/11 全球购物
过滤器的用法
2013/10/08 面试题
城市规划毕业生求职信
2013/10/10 职场文书
在职研究生自我鉴定
2013/10/16 职场文书
网络维护管理员的自我评价分享
2013/11/11 职场文书
日语专业个人的求职信
2013/12/03 职场文书
个人收入证明范本
2014/01/12 职场文书
财务工作个人总结
2015/02/27 职场文书
Go标准容器之Ring的使用说明
2021/05/05 Golang