原文:Pro jQuery 2.0
协议:CC BY-NC-SA 4.0
二十三、使用菜单和工具提示小部件
在本章中,我将描述 jQuery UI 菜单和工具提示小部件。表 23-1 提供了本章的总结。
表 23-1 。章节总结
问题 | 解决办法 | 列表 |
---|---|---|
创建菜单小部件 | 选择一个元素结构,调用 menu 方法;该结构通常使用ul 、li 和a 元素创建 | one |
添加分隔符和禁用的菜单项 | 添加仅包含破折号或空格的元素,并应用ui-state-disabled 类 | Two |
执行基本导航 | 向菜单元素结构中的a 元素添加href 属性 | three |
使用自定义元素结构 | 使用menus 设置 | 4, 5 |
向子菜单添加自定义图标 | 使用icons 设置 | six |
向菜单项添加图标 | 添加分配给ui-icon 类并指定 jQuery UI 图标的span 元素。 | seven |
设置子菜单的位置 | 使用position 设置 | eight |
当菜单项处于活动状态并被选中时接收通知 | 处理blur 、focus 和select 事件 | nine |
创建工具提示小部件 | 选择一个具有title 属性的元素并调用tooltip 菜单 | 10, 11 |
设置工具提示的内容 | 使用content 和items 设置 | 12–15 |
向工具提示添加自定义样式 | 使用tooltipClass 设置和ui-tooltip-content 等级 | 16, 17 |
移动工具提示以跟随鼠标 | 使用track 设置 | Eighteen |
设置工具提示的位置 | 使用position 设置 | Nineteen |
以编程方式控制工具提示 | 调用open 和close 方法 | Twenty |
工具提示显示和隐藏时接收通知 | 处理open 和close 事件 | Twenty-one |
自上一版以来,JQUERY UI 发生了变化
当我写这本书的第一版时,菜单和工具提示小部件还不存在,作为正在进行的扩展 jQuery UI 小部件范围的努力的一部分,已经添加了这些小部件。
使用 jQuery UI 菜单小部件
菜单小部件——顾名思义——提供一个菜单,允许用户在选项树中导航。这个小部件在向用户呈现具有深层结构的内容时非常有用,比如在线商店的产品类别。
创建菜单
菜单小部件依赖于被表达为 HTML 元素结构的菜单结构,这些元素是用menu
方法选择和转换的,如清单 23-1 所示。
清单 23-1 。创建菜单小工具
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
.ui-menu { width: 200px; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("#menu").menu();
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<ul id="menu">
<li><a>Bouquets</a></li>
<li><a>Heirloom Blooms</a></li>
<li><a>Summer Color</a>
<ul>
<li><a>Aster</a></li>
<li><a>Rose</a></li>
<li><a>Orchid</a></li>
</ul>
</li>
<li><a>Wedding Classics</a></li>
<li><a>Exotica</a></li>
</ul>
</body>
</html>
菜单的结构是使用一个ul
元素定义的,其中单个菜单项是包含一个a
元素的li
元素,菜单项的标签取自a
元素的文本。嵌套子菜单可以通过在li
元素中定义一个ul
元素来创建,你可以在图 23-1 中看到将menu
方法应用于列表结构的效果。
图 23-1 。创建简单的菜单小部件
在图中,您可以看到我是如何打开一个子菜单并将鼠标放在一个已显示的项目上的。这个例子演示了菜单小部件的两个关键特征。首先,菜单总是可见的——它不是一个弹出菜单,而是一个网页中的永久功能,类似于亚马逊展示其顶级产品类别的方式。
第二,菜单小部件保留了它所应用到的元素的结构——菜单项不按名称或任何其他特征排序。你可以在图 23-1 中看到,排序被保留了下来,包括子菜单的位置。
提示注意,我已经使用 CSS 将顶层ul
元素的宽度设置为 200 像素。默认情况下,菜单小部件将填充所有可用的水平空间。
格式化菜单项
除了嵌套子菜单之外,元素结构还可以用于格式化菜单项,创建禁用的项目和相关项目组之间的分隔符。清单 23-2 显示了这两种格式。
清单 23-2 。通过元素结构格式化菜单
...
<body>
<h1>Jacqui's Flower Shop</h1>
<ul id="menu">
<li><a>Bouquets</a></li>
<li><a>Heirloom Blooms</a></li>
<li>-</li>
<li><a>Summer Color</a>
<ul>
<li><a>Aster</a></li>
<li><a>Rose</a></li>
<li><a>Orchid</a></li>
</ul>
</li>
<li><a>Wedding Classics</a></li>
<li>-</li>
<li class="ui-state-disabled"><a>Exotica</a></li>
</ul>
</body>
...
任何内容全是空格或破折号的元素都被解释为菜单分隔符——我在清单中添加了两个这样的元素。给ui-state-disabled
类分配一个元素告诉菜单小部件相应的菜单项应该被禁用。你可以在图 23-2 中看到这些添加的结果。
图 23-2 。添加分隔符和禁用菜单项
执行基本导航
菜单小部件的一个常见用途是在组成 web 应用的网页之间提供导航,执行这项任务的最简单方法是在支撑菜单小部件的 HTML 元素结构中的a
元素上定义href
属性。当用户选择一个对应于带有href
属性的a
元素的菜单项时,浏览器将导航到指定的 URL。在清单 23-3 中,你可以看到我是如何将一个href
属性添加到一个菜单项元素中的。
清单 23-3 。向菜单元素添加 href 属性
...
<body>
<h1>Jacqui's Flower Shop</h1>
<ul id="menu">
<li><a>Bouquets</a></li>
<li><a>Heirloom Blooms</a></li>
<li>-</li>
<li><a>Summer Color</a>
<ul>
<li><a href="[`apress.com`](http://apress.com">Aster</a></li)">Aster</a></li>
<li><a>Rose</a></li>
<li><a>Orchid</a></li>
</ul>
</li>
<li><a>Wedding Classics</a></li>
<li>-</li>
<li class="ui-state-disabled"><a>Exotica</a></li>
</ul>
</body>
...
我给其中一个菜单项添加了一个href
属性,这意味着选择Summer Color
➤ Aster
菜单项将导致浏览器导航到Apress.com
。
提示并不是所有的菜单都用来在网页间导航。当用户通过处理select
事件选择一个菜单项时,你可以执行任意的动作,我将在本章后面的使用菜单事件一节中对此进行描述。
配置菜单
菜单小部件支持一系列设置,允许您自定义菜单呈现给用户的方式,如表 23-2 所述。
表 23-2 。菜单设置
环境 | 描述 |
---|---|
disabled | 设置为true 时,禁用整个菜单 |
icons | 指定要在子菜单上使用的图标 |
menus | 指定用于菜单结构的元素 |
position | 指定子菜单相对于主小工具的位置 |
role | 为可访问性设置自定义 ARIA 角色 |
使用不同的元素结构
虽然使用ul
、li
和a
元素来定义菜单是标准技术,但是菜单小部件可以处理任何有明确定义的父子关系的元素结构。在清单 23-4 中,你可以看到我是如何使用div
元素重新定义示例菜单的。
清单 23-4 。为菜单结构使用不同的元素类型
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
.ui-menu { width: 200px; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("#menu").menu();
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="menu">
<div><a>Bouquets</a></div>
<div><a>Heirloom Blooms</a></div>
<div>-</div>
<div><a>Summer Color</a>
<div>
<div><a>Aster</a></div>
<div><a>Rose</a></div>
<div><a>Orchid</a></div>
</div>
</div>
<div><a>Wedding Classics</a></div>
<div>-</div>
<div><a>Exotica</a></div>
</div>
</body>
</html>
当您想用现有的 HTML 元素制作一个菜单时,这是非常有用的,这些元素通常是从模板中生成的,或者是通过 Ajax 从远程服务器获得的。问题是菜单小工具不知道我的哪个div
元素代表子菜单,所以我的所有div
元素都被当作顶级菜单项,如图图 23-3 所示。
图 23-3 。将所有元素视为菜单项的菜单小部件
我可以通过menus
属性给菜单小部件关于元素的信息,这个属性被设置为一个选择器,它匹配我想要的子菜单的元素,如清单 23-5 所示。
清单 23-5 。使用菜单配置属性
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
.ui-menu { width: 200px; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("#menu").menu({
menus: "div.subMenu"
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="menu">
<div><a>Bouquets</a></div>
<div><a>Heirloom Blooms</a></div>
<div>-</div>
<div><a>Summer Color</a>
<div class="subMenu">
<div><a>Aster</a></div>
<div><a>Rose</a></div>
<div><a>Orchid</a></div>
</div>
</div>
<div><a>Wedding Classics</a></div>
<div>-</div>
<div><a>Exotica</a></div>
</div>
</body>
</html>
我已经将我想要作为子菜单的div
元素分配给了subMenu
类,并在创建菜单小部件时为menus
属性指定了一个div.subMenu
选择器。
提示你不必使用一个类,如果你使用了,它也不必被称为subMenu
。任何匹配您的元素的选择器都可以工作。
在菜单中使用图标
icons
设置指定了菜单部件用于子菜单的图标,并被设置为我在第十八章中描述的一个图标的名称。清单 23-6 显示了icons
设置的使用。
清单 23-6 。设置子菜单中使用的图标
...
<script type="text/javascript">
$(document).ready(function () {
$("#menu").menu({
menus: "div.subMenu",
icons: { submenu: "ui-icon-circle-plus" }
});
});
</script>
...
使用定义了submenu
属性的对象来设置icons
属性,该属性又被设置为您想要使用的图标的名称。在清单中,我指定了一个图标,它在一个圆圈中显示一个加号,你可以在图 23-4 中看到效果。
图 23-4 。更改用于子菜单的图标
您可以通过向菜单结构添加span
元素并使用class
属性来指定图标名称,来为单个菜单项指定图标,如清单 23-7 所示。
清单 23-7 。向菜单项添加图标
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
.ui-menu { width: 200px; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("#menu").menu({
icons: { submenu: "ui-icon-circle-plus" }
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<ul id="menu">
<li><a>Bouquets</a></li>
<li><a>Heirloom Blooms</a></li>
<li>-</li>
<li><a>Summer Color</a>
<ul>
<li><a>Aster</a></li>
<li><a>Rose</a></li>
<li><a>Orchid</a></li>
</ul>
</li>
<li>
<a><span class="ui-icon ui-icon-circle-check"></span>Wedding Classics</a>
</li>
<li>-</li>
<li class="ui-state-disabled"><a>Exotica</a></li>
</ul>
</body>
</html>
span
元素必须出现在a
元素中,并被分配给ui-icon
类和代表要显示的图标的类,在本例中为ui-icon-circle-check
。你可以在图 23-5 中看到这种变化的效果。
图 23-5 。向菜单项添加图标
定位弹出子菜单
position
设置决定了弹出菜单出现在哪里,并且使用了我在第十九章中描述的相同的位置格式。我的建议是允许菜单小部件自动定位子菜单,尤其是因为子菜单的弹出窗口是透明的,当弹出窗口位于父小部件上时,您可以看到底层的菜单结构。在清单 23-8 中,你可以看到用于显示子菜单的position
设置,这样它们就位于菜单部件的中心。
清单 23-8 。定位子菜单的弹出窗口
...
<script type="text/javascript">
$(document).ready(function () {
$("#menu").menu({
icons: { submenu: "ui-icon-circle-plus" },
position: {
my: "left center",
at: "center center"
}
});
});
</script>
...
在图 23-6 中可以看到效果,通过弹出菜单可以看到底层菜单项。
图 23-6 。将子菜单弹出窗口放置在菜单小工具上
使用菜单方法
jQuery UI 菜单小部件支持表 23-3 中描述的方法。我不认为这些方法有用,因为它们主要提供了在菜单小部件中驱动导航的方法,这种事情最好留给用户去做。这些方法很容易造成不和谐的用户体验,我建议不要使用它们。
表 23-3 。菜单方式
方法 | 描述 |
---|---|
menu("blur") | 将焦点从菜单上移开–触发blur 事件(将在本章后面描述) |
menu("collapse") | 关闭当前活动的子菜单 |
menu("collapseAll") | 关闭所有打开的子菜单 |
menu("destroy") | 从基础元素中移除菜单小工具 |
menu("disable") | 禁用菜单 |
menu("enable") | 启用菜单 |
menu("expand") | 打开与当前选定菜单项关联的子菜单 |
menu("focus") | 聚焦于菜单项 |
menu("isFirstItem") | 如果当前选择的项目是菜单中的第一项,则返回true |
menu("isLastItem") | 如果当前选择的项目是菜单中的最后一项,则返回true |
menu("next") | 将焦点移到下一个菜单项 |
menu("option") | 更改一个或多个设置 |
menu("previous") | 将焦点移到上一个菜单项 |
menu("refresh") | 更新菜单以反映基础 HTML 元素中的更改 |
menu("select") | 选择活动菜单项,关闭所有打开的子菜单,并触发 select 事件(将在本章后面介绍) |
很难演示这些方法,因为菜单小部件的行为与当前选择的菜单项紧密相关。例如,试图用按钮控制一个菜单是行不通的,因为点击按钮会把焦点从菜单上移开。我的建议是避免使用这些方法,而依靠标准的用户交互来处理我在下一节中描述的事件。
注意菜单部件还定义了可以滚动的导航菜单的方法,但是在撰写本文时,这个特性还不可靠,所以我从表中省略了这些方法。
使用菜单事件
jQuery UI 菜单小部件支持表 23-4 中描述的事件。
表 23-4 。菜单事件
事件 | 描述 |
---|---|
blur | 当菜单失去焦点时触发(该事件可以通过调用blur 方法显式触发) |
create | 创建小部件时触发 |
focus | 当菜单获得焦点和菜单项被激活时触发(该事件可以通过调用focus 方法显式触发) |
select | 当用户选择菜单项或调用 select 方法时触发 |
在清单 23-9 的中,您可以看到我是如何使用blur
和focus
事件来跟踪用户激活了哪些菜单项,以及使用select
事件来响应用户对菜单项的点击。
清单 23-9 。从菜单小部件处理模糊、聚焦和选择事件
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
.ui-menu { width: 200px; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("#menu").menu({
focus: function (e, ui) {
console.log("Focus: " + ui.item.find("a").first().text());
},
blur: function () {
console.log("Blur");
},
select: function (e, ui) {
console.log("Select: " + ui.item.find("a").first().text());
e.preventDefault();
}
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<ul id="menu">
<li><a>Bouquets</a></li>
<li><a>Heirloom Blooms</a></li>
<li>-</li>
<li><a>Summer Color</a>
<ul>
<li><a href="http://apress.com">Aster</a></li>
<li><a>Rose</a></li>
<li><a>Orchid</a></li>
</ul>
</li>
<li><a>Wedding Classics</a></li>
<li>-</li>
<li class="ui-state-disabled"><a>Exotica</a></li>
</ul>
</body>
</html>
这三个事件的处理函数都被传递了一个 jQuery 事件对象(我在第九章中描述过)和一个额外的ui
对象,该对象的item
属性返回一个jQuery
对象。jQuery
对象意味着包含事件对应的 HTML 元素,但是在我写这篇文章的时候,这个属性的值没有为blur
事件正确设置。
考虑到这一点,我通过编写与事件相关的元素所包含的第一个a
元素的文本内容来处理focus
和select
事件,并简单地注意到blur
事件已经被触发。如果您运行此示例并在菜单中导航,您将看到类似如下的输出:
Focus: Bouquets
Blur
Focus: Heirloom Blooms
Blur
Focus: Summer Color
Select: Summer Color
Blur
Focus: Aster
Blur
Focus: Aster
Select: Aster
Blur
Focus: Aster
Blur
我突出显示了写入控制台的一条语句,因为它演示了包含子菜单的项目本身可以被选择——在这种情况下,我能够单击Summer Color
菜单项,即使它包含子菜单。当select
方法的处理程序没有考虑到这一点时,这会导致意外的行为。
提示注意,我在处理select
事件时调用了preventDefault
方法,以阻止浏览器导航到由a
元素的href
属性指定的 URL。
使用 jQuery UI 工具提示小部件
工具提示小部件提供小的弹出窗口,可用于向用户提供有用的上下文信息。工具提示可以是好的或坏的力量。当小心使用时,工具提示可以帮助用户导航一个复杂的过程,但更多时候它们被误用,成为一种干扰或烦恼。
最常见的陷阱是告诉用户一些她已经知道的东西,这样做错过了提供更有用的东西的机会——这在需要复杂数据的 web 表单中最常见。我最近看到的一个例子是在网上报税。税收自然是复杂的,开发人员认为提供工具提示给用户关于每个字段所需数据的信息会很有帮助。这是一种高尚的姿态,但是每个工具提示只是简单地重述了已经从表单标签中明显可见的信息。例如,标签为Birth Date
的表单的工具提示告诉我“输入你的出生日期”没有提供的是我必须使用的格式——月/日/年、日/月/年、*年/月/日、*等等。你可以在网上看到这个问题的例子,每一个都代表着失去了一个为用户提供有用见解的机会。一个相关的问题是工具提示阻止用户完成任务。每当我在税单的关键字段格式上又猜错一次时,就会出现一个模糊了input
元素的工具提示,减缓了我完成这个过程的速度。
我的建议是少用工具提示,仔细考虑它们能给用户带来什么价值。如果你只是简单地重复用户已经拥有的信息,那么重新考虑你的目标。
创建工具提示
jQuery UI tooltip 小部件可以通过tooltip
方法应用于任何 HTML 元素,并且默认显示title
属性的内容,如清单 23-10 所示。
提示主流浏览器无论如何都会使用title
属性来显示工具提示,不需要使用 jQuery UI。tooltip 小部件的优势在于,它允许您将工具提示的样式与应用的其他部分保持一致,控制工具提示的使用方式,以及使用更广泛的内容。
清单 23-10 。创建工具提示小工具
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
[title] { font-weight: bold; font-style:italic }
</style>
<scripttype="text/javascript">
$(document).ready(function () {
$("[title]").tooltip();
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span title="We are at 200 Main St">20 mile radius</span>
of the store for free and $1/mile thereafter.</p>
</body>
</html>
在这个例子中,我定义了一个具有title
属性的span
元素。我选择任何具有title
属性的元素并调用tooltip
方法,为了强调哪些元素有工具提示,我定义了一个使用相同选择器的 CSS 样式。结果是 jQuery UI 创建了一个工具提示小部件,当鼠标悬停在span
元素上时就会显示出来,如图 23-7 中的所示。
图 23-7 。jQuery UI tooltip
使用带有输入元素的工具提示
当与它们相关的元素获得焦点时,工具提示也会显示出来——这在处理input
元素时很有用,因为当用户在表单中切换时,工具提示会为每个元素出现。对一个input
元素应用工具提示和对其他元素一样,如清单 23-11 所示。
清单 23-11 。将工具提示应用于输入元素
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
input { width: 150px; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("input").tooltip();
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<div><label>Name:</label><input title="Use lastname, firstname" /></div>
<div><label>City:</label><input title="Don't include your state" /></div>
</body>
</html>
在这个清单中有两个带有title
属性的input
元素,你可以在图 23-8 中看到跳转元素的效果。
图 23-8 。对输入元素使用工具提示
配置工具提示
工具提示窗口小部件支持一系列设置,允许您自定义窗口小部件呈现给用户的方式,如表 23-5 所述,并在接下来的章节中演示。
表 23-5 。工具提示设置
环境 | 描述 |
---|---|
content | 设置工具提示的内容,可以表示为 HTML 字符串或函数 |
disabled | 设置为true 时禁用工具提示 |
hide | 指定隐藏工具提示时如何显示动画——关于 jQuery UI 动画支持的详细信息,参见第三十四章 |
items | 指定可以缩小为其创建工具提示的元素集的选择器 |
position | 指定工具提示相对于其对应元素的位置 |
show | 指定工具提示显示时的动画方式——关于 jQuery UI 动画支持的详细信息,参见第三十四章 |
tooltipClass | 指定工具提示元素将添加到的附加类,允许对不同类型的工具提示(例如,错误)进行样式设置 |
track | 当设置为true 时,工具提示的位置会随着鼠标在底层 HTML 元素上的移动而改变 |
设置工具提示内容
使用 jQuery UI 工具提示的一个很大的优点是,您可以使用它们来显示丰富的内容,这些内容可以指定为 HTML 的一个片段,也可以通过 JavaScript 函数来指定。你可以在清单 23-12 的中看到第一个,这里我使用content
属性来指定一个包含格式的 HTML 片段。
清单 23-12 。使用内容设置显示格式化的内容
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
span.toolTip { font-weight: bold; font-style:italic }
</style>
<script id="tipContent" type="text/html">
We are at <b>200</b> Main Street
</script>
<script type="text/javascript">
$(document).ready(function () {
$("span.toolTip").tooltip({
content: $("#tipContent").html(),
items: "span.toolTip"
});
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span class="toolTip">20 mile radius</span>
of the store for free and $1/mile thereafter.</p>
</body>
</html>
我定义了一个新的script
元素,但是将type
属性设置为text/html
——这样可以防止浏览器将script
元素的内容视为 JavaScript 或 HTML 内容的一部分。这与用于数据模板的技术是一样的(如第十二章所述),但是我的目标只是在文档的主要部分隐藏一个 HTML 片段,直到我需要它的时候。
我使用content
设置将 HTML 片段传递给工具提示小部件。注意,我必须使用 jQuery 选择包含片段的script
元素,然后调用html
方法来获取其内容——工具提示小部件没有很好地集成到 jQuery 中,只会将 HTML 作为一个字符串。
我还不得不使用items
设置——这是因为我不再使用title
属性,默认情况下工具提示小部件会查找这个属性。如果没有这个改变,对tooltip
方法的调用将忽略我的span
元素。我已经将span
元素添加到一个名为toolTip
的类中,并将它作为我为items
设置提供的选择器的基础。
脚本元素中包含的 HTML 片段被用作工具提示的内容,效果如图 23-9 中的所示,包括我通过b
元素添加的适度样式。
图 23-9 。设置工具提示中内容的样式
提示我在这个例子中展示了格式化的文本,但是您可以使用 jQuery UI 工具提示来显示任何 HTML 内容,包括图像。
用函数生成工具提示内容
我也可以使用函数来指定内容。对于本地生成的工具提示内容,我可以直接从函数中返回一个 HTML 片段,如清单 23-13 所示。
清单 23-13 。从函数生成工具提示内容
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
span.toolTip { font-weight: bold; font-style:italic }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("span.toolTip").tooltip({
content: function () {
if (this.id == "address") {
return "We are at <b>200</b> Main Street";
} else {
return "Fee capped at <i>$20</i> during June!"
}
},
items: "span.toolTip"
});
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span id="address" class="toolTip">20 mile radius</span> of the store for free and
<span id="maxPrice" class="toolTip">$1/mile thereafter.</span></p>
</body>
</html>
在这个例子中,我定义了两个有工具提示的span
元素,并使用我提供给content
设置的函数为每个工具提示赋予独特的内容。当函数被调用时,this
变量的值被设置为触发工具提示内容需求的元素。我使用id
属性获取id
属性的值,并根据元素返回不同的 HTML 片段。你可以在图 23-10 中看到结果。
图 23-10 。使用函数生成工具提示内容
获取远程工具提示内容
还可以使用 Ajax 异步获取工具提示内容,并通过回调向 jQuery UI 提供想要显示的片段。为了演示这是如何工作的,我创建了一个名为tooltips.json
的新 JSON 文件,并将它放在与示例中的其他文件相同的目录中。您可以在清单 23-14 中看到tooltips.json
文件的内容。
清单 23-14 。tooltips.json 文件的内容
{"address": "We are at <b>200</b> Main Street",
"maxPrice": "Fee capped at <i>$20</i> during June!"}
在实际的应用中,服务器通常会为给定的元素发回特定的消息,但是为了简单起见,我的 JSON 文件包含了我的示例所需的所有工具提示内容。在清单 23-15 中,您可以看到我如何获得这些数据并使用它们来提供工具提示内容。
清单 23-15 。获取远程工具提示内容
...
<script type="text/javascript">
$(document).ready(function () {
var tooltipData;
$("span.toolTip").tooltip({
content: function (callback) {
if (tooltipData != null) {
console.log("Requested serviced locally: " + this.id);
return tooltipData[this.id];
} else {
var elemID = this.id;
$.getJSON("tooltips.json", function (data) {
tooltipData = data;
console.log("Requested serviced remotely: " + elemID);
callback(tooltipData[elemID]);
});
}
},
items: "span.toolTip"
});
});
</script>
...
假设 JSON 文件包含我需要的所有值,我可以向服务器发出一个请求,然后存储我为后续工具提示检索的数据——这就是示例中的大部分代码所涉及的内容。这个例子中的关键点是,我传递给getJSON
方法的回调(我在第十四章中描述过)直到之后的用于content
设置的函数完成后才会执行,这意味着我不能简单地返回工具提示的 HTML 片段作为结果。
相反,我的content
函数被传递了一个参数,这是一个当我准备好 HTML 片段时要调用的函数。
...
content: function (callback) {
...
当我的 Ajax 请求完成时,我用我想要显示的数据调用这个函数:
...
callback(tooltipData[elemID]);
...
产生的工具提示与前面的例子没有什么区别,但是显示的内容是通过 Ajax 请求获得的。
提示为了完整起见,我已经包含了这个特性,但是你应该小心使用它。工具提示在向用户提供即时反馈时效果最好,如果 Ajax 请求需要一段时间才能完成,这种情况可能不会发生。
给工具提示添加额外的 CSS 类
通过tooltipClass
设置,您可以指定一个或多个 CSS 类,这些 CSS 类将应用于工具提示以进行自定义样式设置。清单 23-16 提供了一个例子。
清单 23-16 。使用 tooltipClass 设置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
span.toolTip { font-weight: bold; font-style:italic }
*.customTip { border-color: red; }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("span.toolTip").tooltip({
content: function () {
if (this.id == "address") {
return "We are at <b>200</b> Main Street";
} else {
return "Fee capped at <i>$20</i> during June!"
}
},
items: "span.toolTip",
tooltipClass: "customTip"
});
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span id="address" class="toolTip">20 mile radius</span> of the store for free and
<span id="maxPrice" class="toolTip">$1/mile thereafter.</span></p>
</body>
</html>
我为名为customTip
的类定义了 CSS 样式,并使用tooltipClass
设置将该类应用于工具提示。我的样式设置了边框的颜色,结果如图图 23-11 所示。
图 23-11 。将自定义类应用于工具提示
jQuery UI 为工具提示生成的 HTML 包括另一个对样式有用的类。以下是为示例中的一个小部件生成的 HTML 示例:
...
<div id="ui-tooltip-3" role="tooltip" class="ui-tooltip ui-widget ui-corner-all
ui-widget-contentcustomTip" style="top: 210.15625px; left: 161px; display: block;">
<div class="ui-tooltip-content">We are at <b>200</b> Main Street</div>
</div>
...
有一个外部的div
元素,由tooltipClass
设置指定的类应用于该元素,但是工具提示显示的内容包含在一个内部的div
元素中,该元素属于ui-tooltip-content
类。对于高级样式,您可以使用这两个类分别针对小部件及其内容,如清单 23-17 所示。
提示应用于工具提示的其他类,比如ui-widget
和ui-corner-all
,都是 jQuery UI CSS 框架的一部分,我在第三十五章中描述过。
清单 23-17 。分别设计小部件及其内容的样式
...
<style>
span.toolTip { font-weight: bold; font-style:italic }
*.customTip { border-color: red; }
*.ui-tooltip-content { border: thick solid black; margin: 10px; padding: 10px;
background-color: white; }
</style>
...
你可以在图 23-12 中看到这种变化的效果。
图 23-12 。独立于工具提示本身更改工具提示内容的样式
提示如果你想改变工具提示的背景颜色,你需要在用tooltipClass
设置指定的类中将background-image
属性设置为none
。jQuery UI 小部件背景是使用主题中的图像而不是颜色生成的。
跟踪鼠标
当track
设置为true
时,工具提示将跟随鼠标在工具提示对应的 HTML 元素上的移动。当你想根据鼠标的位置改变工具提示的内容,反映底层 HTML 元素的不同区域时,这很有用,如清单 23-18 所示。
清单 23-18 。用工具提示跟踪鼠标的位置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
span.toolTip { font-weight: bold; font-style:italic }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("span.toolTip").tooltip({
content: "Move the mouse",
items: "span.toolTip",
track: true
}).mousemove(function(e) {
$(this).tooltip("option", "content",
"X: " + e.pageX + " Y: " + e.pageY);
});
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span id="address" class="toolTip">20 mile radius</span> of the store for free and
<span id="maxPrice" class="toolTip">$1/mile thereafter.</span></p>
</body>
</html>
我使用track
设置启用跟踪鼠标,并为mousemove
事件设置一个处理函数(如第九章中的所述),该函数使用option
方法更新工具提示显示的内容。这是一个你需要亲身经历才能看到正在执行的更新的例子,但是图 23-13 显示了新行为的快照。
图 23-13 。用工具提示跟踪鼠标的位置
定位工具提示
position
设置指定了工具提示如何相对于它所对应的元素定位,使用了我在第十九章中描述的相同格式。你可以在清单 23-19 中看到一个例子。
清单 23-19 。定位工具提示
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
span.toolTip { font-weight: bold; font-style:italic }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("span.toolTip").tooltip({
content: function () {
if (this.id == "address") {
return "We are at <b>200</b> Main Street";
} else {
return "Fee capped at <i>$20</i> during June!"
}
},
items: "span.toolTip",
position: {
my: "center bottom",
at: "center top"
}
});
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span id="address" class="toolTip">20 mile radius</span> of the store for free and
<span id="maxPrice" class="toolTip">$1/mile thereafter.</span></p>
</body>
</html>
我已经使用了position
设置来指定工具提示应该直接定位在它相关的元素之上,如图 23-14 所示。
图 23-14 。定位工具提示
使用工具提示方法
jQuery UI 工具提示小部件支持表 23-6 中描述的方法。
表 23-6 。工具提示方法
方法 | 描述 |
---|---|
tooltip("close") | 关闭工具提示(如果它是打开的) |
tooltip("destroy") | 从基础 HTML 元素中移除工具提示小部件 |
tooltip("disable") | 禁用工具提示,防止其显示 |
tooltip("enable") | 启用工具提示,允许显示它 |
tooltip("open") | 如果工具提示已关闭,则将其打开 |
tooltip("option") | 设置一个配置 选项 |
值得注意的方法是open
和close
,它们允许对工具提示进行编程控制。在清单 23-20 中,你可以看到我是如何使用这些方法来显示和隐藏 HTML 文档中包含的所有工具提示的。
清单 23-20 。使用打开和关闭方法
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
span.toolTip { font-weight: bold; font-style:italic }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("span.toolTip").tooltip({
content: function () {
if (this.id == "address") {
return "We are at <b>200</b> Main Street";
} else {
return "Fee capped at <i>$20</i> during June!"
}
},
items: "span.toolTip",
position: {
my: "center bottom",
at: "center top"
}
});
$("button").button().click(function (e) {
$("span.toolTip").tooltip(this.id);
});
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span id="address" class="toolTip">20 mile radius</span> of the store for free and
<span id="maxPrice" class="toolTip">$1/mile thereafter.</span></p>
<div>
<button id="open">Open</button>
<button id="close">Close</button>
</div>
</body>
</html>
你可以在图 23-15 中看到效果。
图 23-15 。以编程方式显示和隐藏工具提示
使用工具提示事件
jQuery UI 工具提示小部件支持表 23-7 中描述的事件。
表 23-7 。工具提示事件
事件 | 描述 |
---|---|
close | 工具提示关闭时触发 |
create | 应用小部件时触发 |
open | 当工具提示显示时触发 |
我已经演示了清单 23-21 中的open
和close
事件。处理函数被传递了一个 jQuery 事件对象(如第九章所述)和一个额外的ui
对象,该对象的tooltip
属性返回一个包含工具提示元素的jQuery
对象。
清单 23-21 。处理打开和关闭事件
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<style>
span.toolTip { font-weight: bold; font-style:italic }
span.active { border: medium solid red; padding: 10px; background-color: white }
</style>
<script type="text/javascript">
$(document).ready(function () {
$("span.toolTip").tooltip({
content: function () {
if (this.id == "address") {
return "We are at <b>200</b> Main Street";
} else {
return "Fee capped at <i>$20</i> during June!"
}
},
items: "span.toolTip",
open: function (e, ui) {
$(this).toggleClass("active");
},
close: function (e, ui) {
$(this).toggleClass("active");
}
});
});
</script>
</head>
<body class="ui-widget">
<h1>Jacqui's Flower Shop</h1>
<h3>Color and Beauty to Your Door</h3>
<p>We are pleased to announce that we are starting a home delivery service for
your flower needs. We will deliver within a
<span id="address" class="toolTip">20 mile radius</span> of the store for free and
<span id="maxPrice" class="toolTip">$1/mile thereafter.</span></p>
</body>
</html>
在这个例子中,我通过在与工具提示相关的元素上切换一个名为active
的 CSS 类来处理open
和close
事件(可通过this
变量获得)。效果是当工具提示显示时,该元素被高亮显示,如图图 23-16 所示。
图 23-16 。处理打开和关闭事件
摘要
在本章中,我已经向您展示了 jQuery UI 菜单和工具提示小部件是如何工作的。按照与其他小部件章节相同的格式,我将重点放在这些小部件支持的设置、方法和事件上。在第二十四章中,我描述了第一个 jQuery UI 交互。
二十四、使用拖放交互
除了我在第十八章–第二十三章中展示的小部件,jQuery UI 还包括一组交互。这些是较低级别的构建块,允许您向 web 应用界面添加功能。在这一章中,我描述了可拖动的和可放下的交互,你可以用它们在 HTML 文档中添加拖放操作。
交互遵循与小部件相同的基本结构。它们有设置、方法和事件。我将遵循相同的模式来描述交互,但是我将稍微跳跃一下,以适应一些交互的独特性质。
使用截屏很难显示应用交互的效果。顾名思义,它们依赖于相互作用。我试图告诉你正在发生的事情的本质,但是要真正理解交互,你应该在浏览器中进行实验。本章中的所有例子(以及其他章节)都包含在 Apress 网站(www.apress.com
)的免费源代码/下载区中。表 24-1 对本章进行了总结。
表 24-1 。章节总结
问题 | 解决办法 | 列表 |
---|---|---|
应用可拖动交互 | 使用draggable 方法 | one |
约束元素可以拖动的方向 | 使用axis 设置 | Two |
限制可以拖动元素的区域 | 使用containment 设置 | three |
限制拖动到网格中的单元格 | 使用grid 设置 | four |
延迟拖动一段时间或多个像素 | 使用delay 和distance 设置 | five |
响应被拖动的元素 | 使用start 、drag 和stop 事件 | six |
应用可拖放的交互 | 使用droppable 方法 | seven |
拖动元素时高亮显示可拖放的元素 | 使用activate 和deactivate 事件 | eight |
当可拖动元素与可放下元素重叠时响应 | 使用over 和out 事件 | nine |
指定可拖放元素将接受哪些可拖动元素 | 使用accept 设置 | Ten |
当拖动开始或重叠时,自动将 CSS 类应用于可拖放的元素 | 使用activeClass 和hoverClass 设置 | Eleven |
改变触发over 事件的重叠量 | 使用tolerance 设置 | Twelve |
创建兼容的可拖放元素组 | 使用scope 设置 | Thirteen |
在拖动期间和之后,将可拖动元素留在原位 | 使用helper 设置 | 14, 15 |
操纵 helper 元素以响应可拖放事件 | 使用ui.helper 属性 | Sixteen |
强制可拖动元素与其他元素的边缘对齐 | 使用snap 、snapMode 和snapTolerance 设置 | Seventeen |
创建可拖动的交互
应用了draggable
交互的元素可以在浏览器窗口中移动(拖动)。该元素正常情况下出现在初始文档布局中,但是如果用户在可拖动元素上按住指针并移动鼠标,该元素的位置会发生变化。清单 24-1 提供了一个可拖动交互的演示。
清单 24-1 。使用可拖动交互
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
#draggable {font-size: x-large; border: thin solid black;
width: 5em; text-align: center}
</style>
<script type="text/javascript">
$(document).ready(function() {
$("#draggable").draggable();
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="draggable">
Drag me
</div>
</body>
</html>
在清单 24-1 中,我选择了一个div
元素并调用了draggable
方法来创建一个可拖动的元素。如图 24-1 所示,元素从它的常规位置开始,但是可以被拖动到浏览器窗口的任何地方。注意,文档中的另一个元素h1
不受draggable
方法的影响。
图 24-1 。在浏览器窗口中拖动元素
提示能够拖动元素本身就很有用,但是当与可拖放的交互结合起来时,它会变得更加强大,我将在本章的后面描述这一点。
可拖动的交互是使用一些巧妙的 HTML 和 CSS 实现的。这意味着它几乎可以在任何浏览器中工作,但也意味着可拖动的元素不能与用户操作系统实现的本地拖放进行交互。
提示 HTML5 包括对拖放的支持,通常使用本地操作系统机制来实现。我在我的书HTML5中提供了 html 5 拖放的细节和例子,这本书也是由 Apress 出版的。如果您使用的是 jQuery UI 拖放机制,我建议禁用 HTML5 等价物以避免混淆。为此,将文档中的body
元素的draggable
属性设置为false
。
配置可拖动交互
有很多方法可以配置可拖动交互。表 24-2 总结了可用的最重要的设置,我将在接下来的章节中演示。
表 24-2 。可拖动设置
环境 | 描述 |
---|---|
axis | 将拖动限制在特定方向。默认为false ,表示没有限制,但是您也可以指定x (x 轴)和y (y 轴)。 |
containment | 将可拖动元素限制在屏幕的某个区域。支持的值范围详见表 24-3 。默认为false ,表示没有限制。 |
delay | 指定用户在元素移动之前必须拖动元素的持续时间。默认为0 ,表示没有延迟。 |
distance | 指定用户在元素移动之前必须从其初始位置拖动的距离。默认为1 像素。 |
grid | 强制可拖动元素与网格对齐。缺省值是false ,意味着不使用网格。 |
提示在本章后面的调整拖动&放下部分,我描述了一些改变可拖动和可放下元素之间关系的附加设置。
约束拖曳轴
有几种方法可以约束元素的拖动方式。第一种是使用axis
设置,它允许您将拖动限制在 x 轴或 y 轴。清单 24-2 提供了一个例子。
清单 24-2 。使用轴设置来约束拖动
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
div.dragElement {font-size: large; border: thin solid black;
width: 5em; text-align: center; background-color: lightgray; margin: 4px }
</style>
<script type="text/javascript">
$(document).ready(function() {
$(".dragElement").draggable({
axis: "x"
}).filter("#dragV").draggable("option", "axis", "y");
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="dragV" class="dragElement">
Drag Vertically
</div>
<div id="dragH" class="dragElement">
Drag Horizontally
</div>
</body>
</html>
在清单 24-2 中,我定义了两个div
元素,用 jQuery 选择它们,并调用draggable
方法。我使用 settings 对象最初为两个div
元素定义一个值x
,然后使用 jQuery filter
方法选择dragV
元素,这样我就可以更改y
设置,而不必让 jQuery 再次搜索整个文档。结果是一个div
元素可以垂直拖动,另一个可以水平拖动。你可以在图 24-2 中看到效果。
图 24-2 。约束元素可以拖动的方向
约束拖动区域
您可以限制可以拖动元素的屏幕区域。你可以通过containment
设置来实现。如表 24-3 所述,该设置可以使用多种格式进行设置。
表 24-3 。安全壳设置值
价值 | 描述 |
---|---|
选择器 | 当指定选择器字符串时,可拖动的元素被约束为第一个匹配元素所占据的区域 |
HTMLElement | 可拖动元素被约束到由指定元素占据的区域 |
string | 您可以指定值parent 、document 和window 来限制拖动 |
数字数组 | 您可以使用格式为[x1, y1, x2, y2] 的数字数组来限制拖动到一个区域 |
清单 24-3 显示了containment
设置的使用。
清单 24-3 。使用密封设置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
div.dragElement {font-size: large; border: thin solid black; padding: 4px;
width: 5em; text-align: center; background-color: lightgray; margin: 4px }
#container { border: medium double black; width: 400px; height: 150px}
</style>
<script type="text/javascript">
$(document).ready(function() {
$(".dragElement").draggable({
containment: "parent"
}).filter("#dragH").draggable("option", "axis", "x");
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="container">
<div id="dragH" class="dragElement">
Drag Horizontally
</div>
<div class="dragElement">
Drag within Parent
</div>
</div>
</body>
</html>
在清单 24-3 中,我约束了两个div
元素,使它们只能在它们的父元素中拖动,父元素是一个固定大小的div
元素。对于其中一个可拖动的div
元素,我还应用了axis
设置,这意味着它只能在父元素中水平拖动。你可以在图 24-3 中看到结果。
图 24-3 。限制拖动到父元素
约束拖动到网格
网格设置可用于使可拖动元素在拖动时与网格对齐。此设置的值是一个双元素数组,以像素为单位指定网格的宽度和高度。清单 24-4 显示了正在使用的网格设置。
清单 24-4 。使用网格设置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
#draggable {font-size: large; border: thin solid black; padding: 4px;
width: 100px; text-align: center; background-color: lightgray; margin: 4px; }
</style>
<script type="text/javascript">
$(document).ready(function() {
$("#draggable").draggable({
grid: [100, 50]
})
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="draggable">
Drag Me
</div>
</body>
</html>
在清单 24-4 中,我指定了一个网格,其中的单元格宽 100 像素,高 50 像素。当你拖动元素时,它会从一个(不可见的)单元格快速移动到下一个,如图图 24-4 所示。
图 24-4 。拖动带有网格的元素
捕捉效果很难在屏幕截图中表现出来,这是一个特别受益于交互的例子。
提示只需将自由运动轴的值指定为 1,就可以在一个方向上捕捉到网格。例如,设置值[100, 1]
强制可拖动元素沿 x 轴对齐 100 个像素单元,但允许沿 y 轴自由移动。
延迟拖动
有两种设置允许您延迟拖动动作。您可以使用delay
设置来指定一个时间间隔,这样用户在元素开始移动之前必须拖动元素几毫秒。您也可以使用distance
设置,它强制用户在元素开始跟随鼠标之前进行一定数量的像素的拖动动作。清单 24-5 显示了正在使用的两种设置。
清单 24-5 。使用延迟和距离设置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
#time, #distance {font-size: large; border: thin solid black; padding: 4px;
width: 100px; text-align: center; background-color: lightgray; margin: 4px; }
</style>
<script type="text/javascript">
$(document).ready(function() {
$("#time").draggable({
delay: 1000
})
$("#distance").draggable({
distance: 150
})
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="time">Time Delay</div>
<div id="distance">Distance</div>
</body>
</html>
在清单 24-5 中我有两个可拖动的div
元素,其中一个我用delay
设置配置,另一个用distance
设置配置。当使用delay
时,在元素开始移动之前,用户必须继续拖动指定的毫秒数。在本例中,这是 1000 毫秒。用户不必在这段时间内一直移动鼠标,但必须在整个时间内按住鼠标按钮,并且必须移动鼠标才能开始拖动过程。当时间跨度过去后,可拖动的元素将捕捉到鼠标指针的位置,受我前面展示的网格、区域和轴的约束。
distance
设置有类似的效果,但是用户必须将鼠标指针从元素的起点向任意方向移动至少指定数量的像素。当鼠标移动到那个距离时,可拖动的元素将会吸附到当前的鼠标位置。
使用可拖动方法
可拖动的交互只定义了您看到的由小部件实现的一组核心方法。没有可拖动的特定方法。表 24-4 描述了那些可用的。
表 24-4 。可拖动方法
方法 | 描述 |
---|---|
draggable("destroy") | 从元素中移除交互 |
draggable("disable") | 禁用了可拖动交互 |
draggable("enable") | 启用可拖动交互 |
draggable("option") | 更改一个或多个设置 |
使用可拖动事件
可拖动交互支持一组简单的事件,当元素被拖动时,这些事件会通知您。表 24-5 描述了这些事件。
表 24-5 。可拖动事件
事件 | 描述 |
---|---|
create | 当可拖动交互应用于元素时触发 |
start | 拖动开始时触发 |
drag | 拖动过程中鼠标移动时触发 |
stop | 拖动停止时触发 |
您可以像处理小部件事件一样响应交互事件。清单 24-6 演示了如何处理start
和stop
事件。
清单 24-6 。使用可拖动的开始和停止事件
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
#draggable {font-size: large; border: thin solid black; padding: 4px;
width: 100px; text-align: center; background-color: lightgray; margin: 4px; }
</style>
<script type="text/javascript">
$(document).ready(function() {
$("#draggable").draggable({
start: function() {
$("#draggable").text("Dragging...")
},
stop: function() {
$("#draggable").text("Drag Me")
}
})
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="draggable">
Drag Me
</div>
</body>
</html>
在清单 24-6 中,我使用start
和stop
事件来改变元素被拖动时的内容。这是使用 HTML 和 CSS 实现可拖动交互(以及所有其他 jQuery UI 交互)的好处:即使可拖动元素在屏幕上移动,也可以使用 jQuery 来修改它。你可以在图 24-5 中看到这个例子产生的效果。
图 24-5 。使用可拖动事件在元素被拖动时修改元素
使用可拖放的交互
当你把可拖动的交互和可放下的交互结合起来时,它的真正效用就出现了。您使用droppable
方法创建可删除的元素,但是要获得真正的功能,您需要为交互定义的事件提供处理函数。表 24-6 描述了可用的事件。
表 24-6 。可丢弃事件
事件 | 描述 |
---|---|
create | 应用可拖放交互时触发 |
activate | 当用户开始拖动可拖动元素时触发 |
deactivate | 当用户停止拖动可拖动元素时触发 |
over | 当用户将可拖动元素拖动到可放下元素上时触发(但尚未释放鼠标按钮) |
out | 当用户将可拖动元素拖出可拖放元素时触发 |
drop | 当用户将可拖动的元素放到可放下的元素上时触发 |
你可以用drop
事件创建一个基本的可删除元素,如清单 24-7 所示。
清单 24-7 。创建一个基本的可拖放交互
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
#draggable, #droppable {font-size: large; border: thin solid black; padding: 4px;
width: 100px; text-align: center; background-color: lightgray; margin: 4px;}
#droppable {padding: 20px; position: absolute; left: 5px; bottom: 5px}
</style>
<script type="text/javascript">
$(document).ready(function() {
$("#draggable").draggable();
$("#droppable").droppable({
drop: function() {
$("#draggable").text("Dropped")
}
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="droppable">
Drop Here
</div>
<div id="draggable">
Drag Me
</div>
</body>
</html>
我添加了一个文本内容为Drop Here
的div
元素。我使用 jQuery 选择这个元素并调用 droppable 方法,传入一个为drop
事件定义处理程序的 settings 对象。为了响应这个方法,我使用text
方法更改了可拖动元素的文本。清单 24-7 创建了最乏味的拖放交互,但是它也提供了一个有用的基础来解释可拖动和可放下交互可以一起使用的方式。你可以在图 24-6 中看到这个例子的不同阶段。
图 24-6 。使用简单的拖放操作
这是非常基本的东西。我将可拖动的元素拖到可放下的元素上,然后放开。可拖动元素保持在我离开它的地方,并且它的文本内容被改变以响应drop
事件。在接下来的小节中,我将向您展示如何使用其他可拖放事件来改善体验。
突出显示拖放目标
当用户开始拖动动作时,您可以使用activate
和deactivate
事件来突出显示拖放目标。这通常是一个好主意,因为它给用户一个清晰的信号,告诉用户哪些元素是拖放模型的一部分。清单 24-8 提供了一个例子。
清单 24-8 。响应激活和去激活事件
...
<script type="text/javascript">
$(document).ready(function() {
$("#draggable").draggable();
$("#droppable").droppable({
drop: function() {
$("#draggable").text("Dropped");
},
activate: function() {
$("#droppable").css({
border: "medium double green",
backgroundColor: "lightGreen"
});
},
deactivate: function() {
$("#droppable").css("border", "").css("background-color", "");
}
});
});
</script>
...
当用户开始拖动元素时,我的可拖放元素触发激活事件,我的处理函数使用css
方法为 CSS border
和background-color
属性应用新值。这使得放置目标变亮,向用户表明可放置的元素与被拖动的元素有关系。我使用deactivate
事件移除 CSS 属性值,并在用户释放鼠标按钮时将可放置的元素返回到其原始状态。(无论用户是否将可拖动的元素放到了可放下的元素上,只要拖动停止,就会触发此事件。)你可以在图 24-7 中看到效果。
图 24-7 。使用激活和停用事件
处理重叠元素
您可以通过处理over
和out
事件来改进您的拖放技术。当可拖动元素的 50%位于可放下元素的任何部分时,触发over
事件。当元素不再重叠时,触发out
事件。清单 24-9 显示了如何对这些事件做出响应。
清单 24-9 。使用超出和超出事件
...
<script type="text/javascript">
$(document).ready(function() {
$("#draggable").draggable();
$("#droppable").droppable({
drop: function() {
$("#draggable").text("Dropped");
},
over: function() {
$("#droppable").css({
border: "medium double green",
backgroundColor: "lightGreen"
});
},
out: function() {
$("#droppable").css("border", "").css("background-color", "");
}
});
});
</script>
...
我使用了与前一个例子相同的事件处理函数,但是我将它们与over
和out
事件相关联。当可拖放元素至少有 50%与可拖动元素重叠时,可拖放元素将显示边框和背景色,如图图 24-8 所示。
图 24-8 。响应过度和过度事件
提示50%的限制被称为容差,您可以用不同的容差配置可删除的元素,正如我在“更改重叠容差”一节中演示的那样
配置可拖放的交互
我在这一部分打破了通常的模式,因为这些事件对可丢弃的交互是如此重要。当然,这种交互有许多设置可以用来改变它的行为方式,这些在表 24-7 中有描述。
表 24-7 。可删除的设置
环境 | 描述 |
---|---|
disabled | 当true 时,交互最初被禁用。默认为false 。 |
accept | 缩小可拖放元素将响应的可拖动元素。默认为* ,匹配所有元素。 |
activeClass | 指定将在响应activate 事件时应用并在响应deactivate 事件时移除的类。 |
hoverClass | 指定将在响应over 事件时应用并在响应out 事件时移除的类。 |
tolerance | 指定在触发on 事件之前必须发生的重叠量。 |
提示在“调整拖放”一节中,我描述了一些改变可拖放元素之间关系的附加设置。
限制可接受的可拖动元素
您可以通过应用accept
设置来限制您希望通过可拖放交互接收的元素集。通过提供一个选择器作为值来使用accept
设置。当一个可拖动的元素与选择器匹配时,这样做的效果是只触发可放下的事件。清单 24-10 提供了一个例子。
清单 24-10 。限制可接受的元素
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
.draggable, #droppable {font-size: large; border: thin solid black; padding: 4px;
width: 100px; text-align: center; background-color: lightgray; margin: 4px;}
#droppable {padding: 20px; position: absolute; left: 5px; bottom: 5px}
</style>
<script type="text/javascript">
$(document).ready(function() {
$(".draggable").draggable();
$("#droppable").droppable({
drop: function(event, ui) {
ui.draggable.text("Dropped");
},
activate: function() {
$("#droppable").css({
border: "medium double green",
backgroundColor: "lightGreen"
});
},
deactivate : function() {
$("#droppable").css("border", "").css("background-color", "");
},
accept: "#drag1"
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="droppable">
Drop Here
</div>
<div id="drag1" class="draggable">
Drag 1
</div>
<div id="drag2" class="draggable">
Drag 2
</div>
</body>
</html>
本例中有两个可拖动的元素,id 分别为drag1
和drag2
。在创建可拖放元素时,我使用了accept
设置来指定只接受drag1
元素。当drag1
元素被拖动时,你会看到与上一个例子相同的效果。activate
、deactivate
、over
、out
和drop
事件都在适当的时刻触发。然而,当您拖动drag2
元素时,它无法匹配我为 accept 设置指定的选择器,并且这些事件不会触发。我仍然可以拖动元素,但是我不能再把它放到可拖放的元素上。你可以在图 24-9 中看到效果。
图 24-9 。使用接受设置
注意,我改变了选择拖放元素的方式,这样我就可以调用text
方法。当文档中只有一个可拖动元素时,我只使用了id
属性,如下所示:
...
$("#draggable").text("Dropped");
...
在这个例子中,有多个可拖动的元素,所以通过id
选择不会起作用,因为我将总是改变同一个元素上的文本,而不管哪个元素被拖放。相反,我使用了ui
对象,jQuery UI 将它作为事件处理函数的附加参数。ui
对象的 draggable 属性返回一个 jQuery 对象,该对象包含用户正在拖动或已经放下的元素,允许我如下定位该元素:
...
ui.draggable.text("Dropped");
...
使用类突出显示可删除的
您可以使用activeClass
和hoverClass
设置 来更改可拖放元素的外观,而无需使用activate
、deactivate
、over
和out
事件。清单 24-11 提供了一个演示。
清单 24-11 。使用 activeClass 和 hoverClass 设置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
.draggable, #droppable {font-size: large; border: thin solid black; padding: 4px;
width: 100px; text-align: center; background-color: lightgray; margin: 4px;}
#droppable {padding: 20px; position: absolute; left: 5px; bottom: 5px}
#droppable.active {border: thick solid green}
#droppable.hover {background-color: lightgreen}
</style>
<script type="text/javascript">
$(document).ready(function() {
$(".draggable").draggable();
$("#droppable").droppable({
drop: function(event, ui) {
ui.draggable.text("Dropped");
},
activeClass: "active",
hoverClass: "hover"
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="droppable">
Drop Here
</div>
<div class="draggable">
Drag Me
</div>
</body>
</html>
我定义了两个新的 CSS 样式,我在清单中突出显示了这两个样式。我创建了特定于 draggable 元素的id
(例如#draggable.active
)的类,这样它们比我一直使用的其他样式(例如#droppable
)更加特定,并且它们具有优先权。参见第三章了解 CSS 样式应用于元素的详细规则。
定义了这些样式后,我将它们命名为activeClass
和hoverClass
设置的值。可删除交互负责在可删除元素中添加和删除这些类,以响应事件。你可以在图 24-10 中看到结果。
图 24-10 。使用 activeClass 和 hoverClass 设置
更改重叠公差
默认情况下,只有当至少 50%的可拖动元素与可放下元素重叠时,才会触发over
事件。您可以使用tolerance
设置 进行更改,该设置接受表 24-8 中显示的值。
表 24-8 。公差值
价值 | 描述 |
---|---|
fit | 被拖动的元素必须与可放下的元素完全重叠。 |
intersect | 被拖动元素的至少 50%必须与可拖放元素重叠。这是默认设置。 |
pointer | 无论用户从哪里抓取了可拖动元素,鼠标指针都必须在可拖动元素上。 |
touch | 被拖动的元素必须与可放下的元素重叠任意多的距离。 |
我最常用的两个值是fit
和touch
,因为它们代表了用户最容易理解的方法。当我保存被放下的项目的位置时,我使用fit
,当我让被放下的项目恢复到原来的位置时,我使用touch
(我将在本章后面演示)。清单 24-12 显示了fit
和touch
设置的使用。
清单 24-12 。更改可拖动元素的公差
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
.draggable, .droppable {font-size: large; border: thin solid black; padding: 4px;
width: 100px; text-align: center; background-color: lightgray;}
.droppable {margin-bottom: 10px; margin-right: 5px; height: 50px; width: 120px}
#dropContainer {position: absolute; right: 5px;}
div span {position: relative; top: 25%}
.droppable.active {border: thick solid green}
.droppable.hover {background-color: lightgreen}
</style>
<script type="text/javascript">
$(document).ready(function() {
$(".draggable").draggable();
$("div.droppable").droppable({
drop: function(event, ui) {
ui.draggable.text("Dropped");
},
activeClass: "active",
hoverClass: "hover",
tolerance: "fit"
});
$("#touchDrop").droppable("option", "tolerance", "touch");
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="dropContainer">
<div id="fitDrop" class="droppable">
<span>Fit</span>
</div>
<div id="touchDrop" class="droppable">
<span>Touch</span>
</div>
</div>
<div class="draggable">
<span>Drag Me</span>
</div>
</body>
</html>
在清单 24-12 中,我创建了两个可删除的元素,其中一个用公差设置的fit
值配置,另一个用touch
值配置。有一个单一的可拖动元素,图 24-11 显示了不同值产生的效果。我在over
事件触发的那一刻拍摄了每一张截图。请注意,当tolerance
设置用于确定重叠时,包含了我应用于可拖放元素的边界。
图 24-11 。将“适合”和“接触”值用于公差设置
使用可丢弃的方法
可拖放的交互只定义了您看到的由小部件实现的核心方法集。没有特定于交互的方法。表 24-9 描述了那些可用的。
表 24-9 。可丢弃的方法
方法 | 描述 |
---|---|
droppable("destroy") | 从元素中移除交互 |
droppable("disable") | 禁用了可拖放的交互 |
droppable("enable") | 启用可拖放的交互 |
droppable("option") | 更改一个或多个设置 |
调整拖放
您可以使用一些附加设置来微调 jQuery UI 拖放的工作方式。在本节中,我将描述这些设置并演示它们的用法。
使用元素范围
在本章的前面,我展示了如何使用 drop ableaccept
设置来过滤激活拖放区的元素。使用选择器对于简单的项目来说很好,但是如果您有许多可拖动的元素需要管理,选择器可能会变得过于复杂和容易出错。
另一种方法是将scope
设置应用到可拖动和可放下的元素上。可拖动元素将激活具有相同范围值的可拖放元素。清单 24-13 显示了正在使用的scope
设置。
提示scope
设置可以与accept
设置在可删除元素中结合使用。只有当可拖动元素共享同一个scope
并匹配由accept
设置定义的选择器时,可拖动元素才会被激活。
清单 24-13 。使用范围设置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
.draggable, .droppable {font-size: large; border: medium solid black;
padding: 4px; width: 100px; text-align: center;
background-color: lightgray; margin-bottom: 10px;}
.droppable {margin-right: 5px; height: 50px; width: 120px}
#dropContainer {position: absolute; right: 5px;}
div span {position: relative; top: 25%}
.droppable.active {border: medium solid green}
.droppable.hover {background-color: lightgreen}
</style>
<script type="text/javascript">
$(document).ready(function() {
$("#apple").draggable({
scope: "fruit"
});
$("#orchid").draggable({
scope: "flower"
});
$("#flowerDrop").droppable({
activeClass: "active",
hoverClass: "hover",
scope: "flower"
});
$("#fruitDrop").droppable({
activeClass: "active",
hoverClass: "hover",
scope: "fruit"
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="dropContainer">
<div id="flowerDrop" class="droppable">
<span>Flowers</span>
</div>
<div id="fruitDrop" class="droppable">
<span>Fruit</span>
</div>
</div>
<div id="orchid" class="draggable">
<span>Orchid</span>
</div>
<div id="apple" class="draggable">
<span>Apple</span>
</div>
</body>
</html>
在清单 24-13 中,我创建了两个可拖动的元素和两个可放下的元素。当创建这些元素时,我将它们分配给两个scope
值之一:fruit
和flower
。结果是每个可拖动元素都将被激活,并且只被具有相同范围的可拖放元素接受,如图图 24-12 所示。
图 24-12 。按范围对可拖动和可放下的元素进行分组
注意注意,我在对draggable
和droppable
方法的初始调用中为每个元素定义了scope
,而不是使用option
方法。在我写这篇文章的时候,jQuery UI 中有一个 bug,在交互创建之后分配作用域不起作用。
使用辅助元素
helper
设置 允许您指定一个将被拖动的元素来代替可拖动的元素,保留原来的可拖动元素。这是一个与前面的例子完全不同的效果,在前面的例子中,可拖动元素已经从它的原始位置移开。清单 24-14 展示了一个使用辅助元素的例子。
清单 24-14 。使用大的可拖动元素
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
.draggable, .droppable {font-size: large; border: medium solid black;
padding: 4px; width: 150px; text-align: center;
background-color: lightgray; margin-bottom: 10px;}
.droppable {margin-right: 5px; height: 50px; width: 120px}
#dropContainer {position: absolute; right: 5px;}
div span {position: relative; top: 25%}
.droppable.active {border: medium solid green}
.droppable.hover {background-color: lightgreen}
</style>
<script type="text/javascript">
$(document).ready(function() {
$("div.draggable").draggable({
helper: "clone"
});
$("#basket").droppable({
activeClass: "active",
hoverClass: "hover"
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="dropContainer">
<div id="basket" class="droppable">
<span>Basket</span>
</div>
</div>
<div class="draggable">
<img src="lily.png"/><label for="lily">Lily</label>
</div>
</body>
</html>
值克隆告诉 jQuery UI 复制可拖动元素及其所有内容,并将结果用作辅助元素。你可以在图 24-13 中看到效果。当用户放下辅助元素时,它会被移除,将可拖动和可放下的元素留在原来的位置。
图 24-13 。大的可拖动元素
如图所示,原来的可拖动元素保留在原来的位置,只有辅助元素随着用户的鼠标在屏幕上移动。像本例中这样的大型可拖动元素使得用户很难看到文档中的底层元素,包括可拖放元素的位置。您可以通过提供一个函数作为助手 设置的值来解决这个问题,如清单 24-15 所示。
清单 24-15 。使用助手设置
...
<script type="text/javascript">
$(document).ready(function() {
$("div.draggable").draggable({
helper: function() {
return $("<img src=lily.png />")
}
});
$("#basket").droppable({
activeClass: "active",
hoverClass: "hover"
});
});
</script>
...
当用户开始拖动元素时,jQuery UI 调用helper
函数,并使用它返回的元素作为可拖动的项目。在本例中,我使用 jQuery 创建一个img
元素。你可以在图 24-14 中看到效果。
图 24-14 。使用助手
较小的图像充当可拖动元素的更紧凑的替身,使得在拖动时更容易看到文档的其余部分。
操作辅助元素
jQuery UI 传递给 droppable events 的ui
对象包含一个helper
属性,您可以使用该属性在拖动 helper 元素时对其进行操作。清单 24-16 展示了这个属性的使用,与over
和out
事件相关联。
清单 24-16 。使用 ui.helper 属性
...
<script type="text/javascript">
$(document).ready(function() {
$("div.draggable").draggable({
helper: function() {
return $("<img src=lily.png />")
}
});
$("#basket").droppable({
over: function(event, ui) {
ui.helper.css("border", "thick solid green")
},
out: function(event, ui) {
ui.helper.css("border", "")
}
});
});
</script>
...
我使用over
和out
事件以及ui.helper
属性在辅助元素与可拖放元素重叠时显示一个边框。你可以在图 24-15 中看到结果。
图 24-15 。操作辅助元素
对齐元素的边缘
您可以使用snap
设置 使可拖动元素捕捉到它经过的元素的边缘。此设置的值是一个选择器。draggable 将与它附近与选择器匹配的任何元素的边缘对齐。清单 24-17 显示了snap
设置的使用。
清单 24-17 。使用捕捉设置
<!DOCTYPE html>
<html>
<head>
<title>Example</title>
<script src="jquery-2.0.2.js" type="text/javascript"></script>
<script src="jquery-ui-1.10.3.custom.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="styles.css"/>
<link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
<style type="text/css">
#snapper, .draggable, .droppable {font-size: large; border: medium solid black;
padding: 4px; width: 150px; text-align: center;
background-color: lightgray; margin-bottom: 10px;}
.droppable {margin-right: 5px; height: 50px; width: 120px}
#dropContainer {position: absolute; right: 5px;}
div span {position: relative; top: 25%}
.droppable.active {border: medium solid green}
.droppable.hover {background-color: lightgreen}
#snapper {position: absolute; left: 35%; border: medium solid black;
width: 180px; height: 50px}
</style>
<script type="text/javascript">
$(document).ready(function() {
$("div.draggable").draggable({
snap: "#snapper, .droppable",
snapMode: "both",
snapTolerance: 50
});
$("#basket").droppable({
activeClass: "active",
hoverClass: "hover"
});
});
</script>
</head>
<body>
<h1>Jacqui's Flower Shop</h1>
<div id="dropContainer">
<div id="basket" class="droppable">
<span>Basket</span>
</div>
</div>
<div id="snapper"><span>Snap Here</span></div>
<div class="draggable">
<span>Drag Me</span>
</div>
</body>
</html>
当可拖动元素靠近其中一个匹配元素时,它会跳跃(捕捉)以便两个最近的边接触。您可以选择任何要捕捉的元素,而不仅仅是可删除的元素。在清单 24-17 中,我添加了一个div
元素并为snap
设置定义了一个值,该值用于选择它和文档中可拖放的元素。使用屏幕截图来展示截图的效果几乎是不可能的,所以我鼓励您在浏览器中尝试这个例子。
有几个支持设置可用于调整捕捉行为。snapMode
第一个是。通过此设置,您可以指定可拖动对象将吸附到哪些边缘。可接受的值有inner
(对齐基础元素的内边缘)、outer
(对齐外边缘)和both
(对齐所有边缘,这是默认值)。
您使用snapTolerance
设置来指定可拖动元素在捕捉到位置之前必须远离目标多远。默认为20
,表示 20 像素。在清单 24-17 的中,我指定了一个50
的值,这使得捕捉发生在更远的地方。为此设置获取正确的值非常重要。如果snapTolerance
值太小,用户不会注意到对齐效果,如果值太大,可拖动元素开始意外地跳过屏幕,以对齐远处的元素
摘要
在本章中,我向您介绍了 jQuery UI 交互中最重要和最有用的两种:draggable 和 droppable。我向您展示了如何单独应用和配置这些交互,如何响应它们的事件,以及如何调整它们协同工作的方式,以获得对您向 web 应用用户提供的拖放体验的细粒度控制。在第二十五章中,我将向您展示其他 jQuery UI 交互。