JQuery UI的拖拽功能

JQuery UI是JQuery官方支持的WebUI 代码库,包含底层交互、动画、特效等API,并且封装了一些Web小部件(Widget)。同时,JQuery UI继承了jquery的插件支持,有大量的第三方插件可以丰富JQuery UI的功能。

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之前,页面元素不直接支持拖拽事件。所以都是通过监听鼠标事件并记录拖拽状态的方式来实现拖拽功能。

最简单的例子

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

01<html>
02<head></head>
03<body>
04<divid="container">
05<divid="dragsource">
06<p>拽我!</p>
07</div>
08</div><!-- End container -->
09<scripttype="text/javascript"src="js/jquery-1.7.min.js"></script>
10<scripttype="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
11<script>
12$(function() {
13$( "#dragsource" ).draggable();
14})
15</script>
16</body>
17</html>

拖动到另一个容器

更常见的场景是将元素拖动到另一个容器中。这就需要在drop目标(target)容器上应用droppable函数。让我们在上一个例子的基础上,增加一个div作为容器,并应用droppable函数:

01<html>
02<head></head>
03<body>
04<div string">"container">
05<div string">"dragsource">
06<p>拽我!</p>
07</div>
08</div><!-- End container -->
09
10<div string">"droppalbe"string">"width: 300px;height:300px;background-color:gray">
11<p>Drop here</p>
12</div>
13
14<script type="text/javascript"src="js/jquery-1.7.min.js"></script>
15<script type="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
16<script>
17$(function() {
18$("#dragsource").draggable();
19$("#droppable").droppable();
20})
21</script>
22</body>
23</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。看一下实际的例子:

01<html>
02<head>
03
04</head>
05<body>
06<div string">"dragsource">
07<p string">"targetMsg">:-|</p>
08</div>
09
10<div string">"droppable"string">"background-color:gray;height:300">
11<p>Can drop! </p>
12</div>
13
14<script type="text/javascript"src="js/jquery-1.7.min.js"></script>
15<script type="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
16<script>
17$(function() {
18$("#dragsource").draggable({
19start:function(event,ui) {
20$(this).find("p").html(":-S");
21},
22stop:function(event,ui){
23$(this).find("p").html(":-|");
24}
25});
26
27$("#droppable").droppable({
28activate:function(event,ui) {
29$(this).find("p").html("Drop here !");
30},
31over:function(event,ui) {
32$(this).find("p").html("Oh, Yeah!");
33
34},
35out:function(event,ui) {
36$(this).find("p").html("Don't leave me!");
37
38},
39drop:function( event, ui ) {
40$(this).find("p").html("I've got it!");
41}
42});
43})
44</script>
45</body>
46</html>

复制拖动

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

helper可以指定为“original”, "clone",其中"original"是默认值,即拖动自身,而clone表示创建自身的一个克隆用于拖拽。helper还可以指定为函数,该函数返回一个自定义的DOM元素用于拖拽。

当不是拖动自身的时候,需要在target上指定drop事件函数,在该函数中将特定的元素添加到target容器上,否则drop的时候什么事情都不会发生。

简单复制的例子如下:

01<html>
02<head></head>
03<body>
04
05<div string">"dragsource">
06<p>拽我!</p>
07</div>
08<div string">"container"string">"background-color:gray;height:300">
09</div><!-- End container -->
10<script type="text/javascript"src="js/jquery-1.7.min.js"></script>
11<script type="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
12<script>
13$(function() {
14$("#dragsource").draggable({
15helper:"clone"
16});
17
18$("#container").droppable({
19drop:function(event,ui){
20$(this).append($("<p+
21ui.offset.left+";top:"+ui.offset.top+"'>clone</p>"));
22}
23});
24})
25</script>
26</body>
27</html>

拖动控制

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

拖动方向

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

01<html>
02<head></head>
03<body>
04
05<div string">"dragX">
06<p>--</p>
07</div>
08<div string">"dragY">
09<p>|</p>
10</div>
11
12<script type="text/javascript"src="js/jquery-1.7.min.js"></script>
13<script type="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
14<script>
15$(function() {
16$("#dragX").draggable({axis:"x"});
17$("#dragY").draggable({axis:"y"});
18});
19</script>
20</body>
21</html>

拖动范围

除了方向之外,还可以通过containment参数约束拖动的范围。该参数接受Selector, Element, String, Array类型。其中String可以为parent,document,window,Array是指定一个矩形区域(regin)的四元数组: [x1,y1,x2,y2]。下面的例子分别指定了parent和regin作为范围限制:

01<html>
02<head></head>
03<body>
04<div string">"container"string">"background-color:gray;height:300">
05<div string">"draggable1"string">"background-color:red;height:20;width:100">
06<p>inparent</p>
07</div>
08
09<div string">"draggable2"string">"background-color:green;height:20;width:100">
10<p>inregin</p>
11</div>
12
13<script type="text/javascript"src="js/jquery-1.7.min.js"></script>
14<script type="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
15<script>
16$(function() {
17$("#draggable1").draggable({containment:"parent"});
18$("#draggable2").draggable({containment: [20,20,300,200] });
19});
20</script>
21</body>
22</html>

拖动吸附

还可以在拖动的时候吸附到其他元素或网格。使用snap参数指定要吸附到的元素,使用grid参数指定吸附到网格,如下:

01<html>
02<head>
03<style>
04.draggable {background-color:green; width: 90px; height: 80px; padding: 5px; float: left; margin: 0 10px 10px 0; font-size: .9em; }
05</style>
06</head>
07<body>
08<div string">"container"string">"background-color:gray;height:300">
09<div string">"draggable1"class="draggable">
10<p>吸附到其他可拖拽元素</p>
11</div>
12
13<div string">"draggable2"class="draggable">
14<p>吸附到容器</p>
15</div>
16
17<div string">"draggable3"class="draggable">
18<p>吸附到网格(30x30)</p>
19</div>
20</div><!--container-->
21
22<script type="text/javascript"src="js/jquery-1.7.min.js"></script>
23<script type="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
24<script>
25$(function() {
26$("#draggable1").draggable({ snap:true});
27$("#draggable2").draggable({ snap:"#container"});
28$("#draggable3").draggable({grid: [30,30]});
29});
30</script>
31</body>
32</html>

拖动把手(handle)

默认是整个元素都可以拖动,也可以指定元素的某个子元素作为拖动的handle,如:

1<div string">"draggable">
2<p>handle</p>
3</div>
4……
5<script>
6$("#draggable").draggable({handle:"p"});
7</script>

Drop限制

默认的droppable指定元素能够接受所有的drop, 但是可以通过accept参数限定只能接受某些元素的drop。accept参数的类型为一个符合jquery selector的字符串。例如:

$(".selector").droppable({ accept: '.special' })

表示只接受具有special 样式的元素。

增强用户体验

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

查看源码

打印?
01<html>
02<head>
03<style>
04.draggable {background-color:green; width: 90px; height: 80px; padding: 5px; float: left; margin: 0 10px 10px 0; font-size: .9em; }
05.droppable { width: 300px; height: 300px; background-color:red}
06
07</style>
08</head>
09<body>
10<div string">"draggable2"class="draggable">
11<p>I revert when I'm not dropped</p>
12</div>
13
14<div string">"droppable"class="droppable">
15<p>Drop me here</p>
16</div>
17<script type="text/javascript"src="js/jquery-1.7.min.js"></script>
18<script type="text/javascript"src="js/jquery-ui-1.8.16.custom.min.js"></script>
19<script>
20$(function() {
21$("#draggable2").draggable({ revert:"invalid",cursor:"move", cursorAt: { top: 56, left: 56 } });
22$("#droppable").droppable({
23activeClass:"ui-state-hover",
24hoverClass:"ui-state-active",
25drop:function( event, ui ) {
26$(this)
27.addClass("ui-state-highlight")
28.find("p")
29.html("Dropped!");
30}
31});
32});
33</script>
34</body>
35</html>

小结

JQuery UI提供了强大的拖拽功能和良好的用户体验,同时又非常容易使用。本文介绍了常用的各种用法。更多的参数还可以参考项目主页的DraggableDroppable

转自:http://www.cnblogs.com/holbrook/archive/2012/03/13/2394111.html