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 相关文章推荐
网页上的Javascript编辑器和代码格式化
Apr 25 Javascript
Javascript的getYear、getFullYear、getUTCFullYear异同分享
Nov 30 Javascript
Juery解决tablesorter中文排序和字符范围的方法
May 06 Javascript
jQuery三级下拉列表导航菜单代码分享
Apr 15 Javascript
JS实现的网页背景闪电闪烁效果代码
Oct 17 Javascript
jQuery实现的超简单点赞效果实例分析
Dec 31 Javascript
微信小程序 Audio API详解及实例代码
Sep 30 Javascript
10分钟上手vue-cli 3.0 入门介绍
Apr 04 Javascript
AngularJS实现的base64编码与解码功能示例
May 17 Javascript
node.js使用redis储存session的方法
Sep 26 Javascript
JavaScript Array对象使用方法解析
Sep 24 Javascript
解决vue项目router切换太慢问题
Jul 19 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并发运行
2006/10/09 PHP
PHP实现加强版加密解密类实例
2015/07/29 PHP
学习jquery之一
2007/04/27 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
2014/09/28 Javascript
javascript实现淡蓝色的鼠标拖动选择框实例
2015/05/09 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
2016/08/29 Javascript
JavaScript中关于iframe滚动条的去除和保留
2016/11/17 Javascript
js实现符合国情的日期插件详解
2017/01/19 Javascript
JS字符串按逗号和回车分隔的方法
2017/04/25 Javascript
微信分享调用jssdk实例
2017/06/08 Javascript
vue初尝试--项目结构(推荐)
2018/01/30 Javascript
ajax请求+vue.js渲染+页面加载的示例
2018/02/11 Javascript
使用watch监听路由变化和watch监听对象的实例
2018/02/24 Javascript
Vue自定义指令实现checkbox全选功能的方法
2018/02/28 Javascript
微信小程序将字符串生成二维码图片的操作方法
2018/07/17 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
vue动态设置img的src路径实例
2018/09/18 Javascript
Vue中的验证登录状态的实现方法
2019/03/09 Javascript
Python 列表理解及使用方法
2017/10/27 Python
酷! 程序员用Python带你玩转冲顶大会
2018/01/17 Python
Django数据库表反向生成实例解析
2018/02/06 Python
python实现pdf转换成word/txt纯文本文件
2018/06/07 Python
python实现爬取图书封面
2018/07/05 Python
Pandas中DataFrame的分组/分割/合并的实现
2019/07/16 Python
html5新特性与用法大全
2018/09/13 HTML / CSS
违反工作纪律检讨书
2014/02/15 职场文书
感恩节活动策划方案
2014/05/16 职场文书
2014年电工工作总结
2014/11/20 职场文书
起诉离婚协议书样本
2014/11/25 职场文书
环卫工人慰问信
2015/02/15 职场文书
质量保证书格式
2015/02/27 职场文书
行政申诉状范文
2015/05/20 职场文书
合同范本之电脑出租
2019/08/13 职场文书
Python代码,能玩30多款童年游戏!这些有几个是你玩过的
2021/04/27 Python
MySQL修炼之联结与集合浅析
2021/10/05 MySQL
oracle数据库去除重复数据
2022/05/20 Oracle