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 UI 应用不同Theme的办法
Sep 12 Javascript
JavaScript实现在页面间传值的方法
Apr 07 Javascript
浅谈JavaScript中的作用域和闭包问题
Jul 07 Javascript
javascript省市区三级联动下拉框菜单实例演示
Nov 29 Javascript
JavaScript基础知识之方法汇总结
Jan 24 Javascript
Bootstrap table学习笔记(2) 前后端分页模糊查询
May 18 Javascript
vue2.0.js的多级联动选择器实现方法
Feb 09 Javascript
vue2中使用less简易教程
Mar 27 Javascript
vuex 项目结构目录及一些简单配置介绍
Apr 08 Javascript
JS实现判断有效的数独算法示例
Feb 25 Javascript
微信小程序点餐系统开发常见问题汇总
Aug 06 Javascript
Vue防止白屏添加首屏动画的实例
Oct 31 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的FTP学习(二)[转自奥索]
2006/10/09 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
ThinkPHP5.0多个文件上传后找不到临时文件的修改方法
2018/07/30 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
PHP集成环境XAMPP的安装与配置
2018/11/13 PHP
php封装的pdo数据库操作工具类与用法示例
2019/05/08 PHP
Laravel validate error处理,ajax,json示例
2019/10/25 PHP
简单的JS多重继承示例
2008/03/13 Javascript
从URL中提取参数与将对象转换为URL查询参数的实现代码
2012/01/12 Javascript
js实现滑动触屏事件监听的方法
2015/05/05 Javascript
js控制网页前进和后退的方法
2015/06/08 Javascript
jQuery使用deferreds串行多个ajax请求
2016/08/22 Javascript
js实现返回顶部效果
2017/03/10 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
bootstrap table表格使用方法详解
2017/04/26 Javascript
vue子组件使用自定义事件向父组件传递数据
2017/05/27 Javascript
jQuery实现的中英文切换功能示例
2019/01/11 jQuery
layer.alert自定义关闭回调事件的方法
2019/09/27 Javascript
基于JS实现快速读取TXT文件
2020/08/25 Javascript
[43:32]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS NewBee第一场
2014/05/26 DOTA
跟老齐学Python之有容乃大的list(3)
2014/09/15 Python
跟老齐学Python之大话题小函数(1)
2014/10/10 Python
在Python中操作字符串之startswith()方法的使用
2015/05/20 Python
Python数组定义方法
2016/04/13 Python
Python实现命令行通讯录实例教程
2016/08/18 Python
Flask框架工厂函数用法实例分析
2019/05/25 Python
浅谈pytorch grad_fn以及权重梯度不更新的问题
2019/08/20 Python
wxPython之wx.DC绘制形状
2019/11/19 Python
python 实现一个简单的线性回归案例
2020/12/17 Python
详解Python中的Lock和Rlock
2021/01/26 Python
曼联官方网上商店:Manchester United Direct
2017/07/28 全球购物
班级入场式解说词
2014/02/01 职场文书
创业女性典型材料
2014/05/02 职场文书
大学生入党推荐书范文
2014/05/17 职场文书
cf战队宣传语
2015/07/13 职场文书
win server2012 r2服务器共享文件夹如何设置
2022/06/21 Servers