首页 前端知识 jQuery2 高级教程(七)

jQuery2 高级教程(七)

2024-08-24 23:08:14 前端知识 前端哥 380 809 我要收藏

原文:Pro jQuery 2.0

协议:CC BY-NC-SA 4.0

十七、设置 jQuery UI

下载和安装 jQuery UI 比其他 JavaScript 库更复杂。这并不麻烦,但需要一些解释,我在这一章中提供了。您只需要为这本书的开发做好准备,但是我也包括了如何安装适合生产部署的最小化文件以及如何通过内容分发网络(CDN)使用 jQuery UI 的细节。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意正如我在第一章中所解释的,jQuery UI API 随着 1.10 版本的发布而发生了变化,我将在接下来的章节中重点介绍这些变化。

获取 jQuery UI

jQuery UI 中有四个主要的功能区域,您可以创建一个自定义下载来包含和配置每一个区域。在本书的这一部分,我向您展示了 jQuery UI 的所有特性,但是对于真正的 web 应用,您可以省略不需要的部分,并创建一个较小的库供浏览器下载。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示 jQuery UI 并不是唯一基于 jQuery 的 UI 工具包,尽管它是目前最流行的。另一个选择是 jQuery Tools,它是开源的,可以从http://flowplayer.org/tools下载,没有任何许可或限制。还有一些商业上的替代品,比如 jQWidgets ( www.jqwidgets.com)和 Wijmo ( http://wijmo.com)。当然,还有 jQuery Mobile,我在本书的第五部分对此进行了描述。

决定主题

在构建自定义 jQuery UI 库之前,您需要选择一个主题。jQuery UI 是无限可配置的,您可以更改您使用的每个特性的外观。事实上,有这么多的选择,它可以有些不知所措。jQuery UI web 站点包括一个用于创建定制主题的工具,但是还有一个预定义主题库,您可以选择这些主题来简化工作。

首先,转到http://jqueryui.com并点击Themes按钮。这将加载主题滚轮页面,该页面由一个 jQuery UI 小部件的显示和一个左侧面板组成,该面板允许您配置主题设置,如图图 17-1 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 17-1 。jQuery UI 网站主题页面

如果您需要遵循某种视觉样式来使 jQuery UI 适应站点或应用的其余部分,请使用 Roll Your Own 选项卡(默认情况下选中)。您可以更改 jQuery UI 使用的主题的各个方面。

预定义的主题在图库选项卡上可用。当我写这篇文章时,画廊里有 24 个主题可供选择,它们从低调和微妙到明亮和花哨。当你点击每个图库主题时,页面其余部分的窗口小部件会更新,向你展示你的应用的外观,如图 17-2 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 17-2 。展示阳光主题的画廊

jQuery UI 的默认主题叫做 UI 亮度,但是它没有足够的对比度来很好地显示在图书页面上,所以我将使用阳光主题,它显示得稍微好一点。目前你不需要对主题做任何事情,除了记住你想用哪一个。这些主题打印出来时看起来不太好,但它们在屏幕上有更好的外观,我建议你浏览列表,直到找到你喜欢的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示你不必选择我将使用的相同主题,但如果你选择不同的主题,你显然会得到与我不同的结果。

创建 jQuery UI 自定义下载

既然已经有了主题,就可以创建 jQuery UI 下载了。点击页面顶部的Download按钮,进入构建您的下载页面。

第一步是选择想要下载的 jQuery UI 版本。当我写这篇文章时,最新的版本是1.10.3,这也是我将在本书中使用的版本。

除了指定 jQuery UI 版本之外,该页面还有一个 jQuery UI 组件列表,分为四个功能组: UI 核心交互小部件效果

通过只选择项目所需的功能,您可以创建一组较小的文件供浏览器下载。我认为这是一个不错的想法,但我倾向于不使用它,因为我更喜欢通过使用 CDN 来减少交付 jQuery UI 所需的带宽,我在“通过内容分发网络使用 jQuery UI”一节中向您展示了如何做到这一点

对于这一章,您将需要所有的组件,所以确保所有四个选项都被选中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示列表中的一些组件依赖于其他组件,但是在构建自定义的 jQuery UI 库时,你不必担心这一点。当您启用一个组件时,它所依赖的任何其他组件也会被加载。

下一步是选择你想要的主题。这个选择器在页面的底部,就在下载按钮的上方,如图图 17-3 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 17-3 。选择主题

一旦您选择了所有的组件、您想要的主题和稳定版本,单击Download按钮下载定制的 jQuery UI 库。

安装用于开发的 jQuery UI

jQuery UI 下载是一个 zip 文件,包含开发和生产所需的所有文件。对于本书,您将使用包含未统一源代码的开发文件。如果您遇到问题,这使得查看 jQuery UI 的内部变得很容易。您需要将以下内容复制到包含示例文件的文件夹中:

  • js\jquery-ui-1.10.3.custom.js文件
  • themes\sunny\jquery-ui-1.10.3.custom.css文件
  • themes\sunny\images文件夹

您会注意到在uithemes文件夹中有针对单个组件和特性的 JavaScript 和层叠样式表(CSS)文件。您不需要使用它们,但是如果您只需要使用有限的 jQuery UI 特性,它们会很有帮助。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示JavaScript 和 CSS 文件的名称包括下载的版本号。对我来说,这是 1.10.3 版本。jQuery UI 正在积极开发中,您可能已经下载了更高版本。如果是这样,您需要在 HTML 示例中更改对 jQuery UI 文件的引用。

向 HTML 文档添加 jQuery UI

剩下的就是将 jQuery UI 添加到一个示例 HTML 文档中,这是通过引用我在上一节中列出的 JavaScript 和 CSS 文件的scriptlink元素来完成的,如清单 17-1 所示。

清单 17-1 。向 HTML 文档添加 jQuery UI

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="jquery-ui-1.8.16.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.8.16.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function() {
            $("a").button();
        });
    </script>
</head>
<body>
    <a href="http://apress.com">VisitApress</a>
</body>
</html>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示你不需要直接查阅images目录。只要图像目录和 CSS 文件在同一个地方,jQuery UI 就能够找到它需要的资源。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示 jQuery UI 依赖于 jQuery。为了使用 jQuery UI,您必须将 jQuery 添加到文档中。

清单中显示的文档包括一个简单的测试,允许您检查 jQuery UI 是否已经正确添加。如果你在浏览器中查看这个,你应该会看到一个类似于图 17-4 中的按钮。不用担心对清单中的script元素中的button方法的调用。我会在第十八章的中解释这是做什么的以及它是如何工作的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 17-4 。检查 jQuery UI 是否已经正确添加到文档中

如果你没有正确指定这两个文件的路径,那么你会看到一个简单的a元素,如图 17-5 中的所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 17-5 。识别问题将 jQuery UI 导入到文档中

为生产安装 jQuery UI

当您完成 web 应用的开发并准备好部署它时,您可以使用 jQuery UI 下载中包含的精简文件。这个文件更小,但是为了调试的目的更难阅读。要使用生产文件,您必须将以下内容复制到 web 服务器目录中:

  • js\jquery-ui-1.10.3.custom.min.js文件
  • themes\sunny\jquery-ui-1.10.3.custom.css文件
  • themes\sunny\images文件夹

images目录和 CSS 文件与开发版相同;只有 JavaScript 文件发生了变化。

通过内容分发网络使用 jQuery UI

我在第五章的中提到了使用 CDN 进行 jQuery。如果这是一种吸引你的方法,你会很高兴地得知你可以用 jQuery UI 做同样的事情。Google 和微软都将 jQuery UI 文件放在他们的 cdn 上。对于这个例子,我将使用 Microsoft 服务,因为它托管标准主题以及 jQuery UI JavaScript。

要使用 CDN,你只需要你想要的文件的 URL。对于微软服务,请转到www.asp.net/ajaxlibrary/cdn.ashx开始使用。如果您向下滚动页面,您将看到一个 jQuery UI 发布的部分,按版本细分。单击您正在使用的版本的链接。您将看到 jQuery UI 库文件的常规和最小化版本的 URL。对于我写这篇文章时的最新版本,最小化文件的 URL 如下:

http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/jquery-ui.min.js

页面的其余部分显示了每个预定义的 jQuery UI 主题,主题 CSS 的 URL 显示在下面。阳光主题的网址如下:

http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/themes/sunny/jquery-ui.css

要在 CDN 上使用这些文件,只需将 URL 放在引用本地 jQuery UI 文件的scriptlink元素中,如清单 17-2 所示。

清单 17-2 。通过 CDN 使用 jQuery UI

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="[`ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/jquery-ui.min.js`](http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/jquery-ui.min.js)"
        type="text/javascript"></script>
    <link
    href="[`ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/themes/sunny/jquery-ui.css`](http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/themes/sunny/jquery-ui.css)"
        rel="stylesheet" />
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <script type="text/javascript">
        $(document).ready(function () {
            $("a").button();
        });
    </script>
</head>
<body>
    <a href="http://apress.com">VisitApress</a>
</body>
</html>

同样,你可以通过加载文档并查看浏览器是否显示一个类似于图 17-4 中的按钮来判断你是否有正确的 URL。

摘要

在本章中,我向您展示了创建和准备 jQuery UI 下载所需的步骤。在包含的特性和 jQuery UI 赋予 web 应用的默认外观方面有很大的灵活性。我特别喜欢 ThemeRoller 应用。这是一种创建完全定制的主题以适应现有视觉方案的优雅方式,非常适合将 jQuery UI 添加到公司品牌的站点。在下一章中,您将开始研究不同的 jQuery UI 特性,从最流行的功能领域开始:小部件。

十八、使用按钮、进度条和滑块小部件

现在您已经配置、下载并安装了 jQuery UI,您可以开始查看它包含的小部件了。这些是 jQuery UI 的主要功能块,尽管还有其他特性(比如效果,我在第三十五章中描述过),jQuery UI 还是以小部件而闻名。

在这一章中,我描述了三个最简单的部件:按钮、进度条和滑块。所有 jQuery UI 小部件都有共同的特征:设置、方法和事件。掌握一个小部件为使用所有这些部件提供了坚实的基础,所以我在本章开始时花了一些时间来提供整体背景。

很难将所有的小部件都绑定到花店示例中,因此您会发现本书这一部分中的许多示例都是小型的、自包含的 HTML 文档,它们演示了一个小部件。当我重构它以包含 jQuery UI 时,我回到了第二十六章中的花店示例。表 18-1 对本章进行了总结。

表 18-1 。章节总结

问题解决办法列表
创建 jQuery UI 按钮选择一个元素并使用button方法one
配置按钮元素将地图对象传递给button方法或使用option方法2, 3
在 jQuery UI 按钮中使用图标使用icons设置four
在 jQuery UI 按钮中使用自定义图像将按钮的内容设置为一个img元素five
删除 jQuery UI 按钮小部件使用destroy方法six
启用或禁用 jQuery UI 按钮使用enabledisable方法seven
刷新 jQuery UI 按钮的状态,以反映对基础元素的编程更改使用refresh方法eight
响应正在创建的 jQuery UI 按钮create事件指定一个函数nine
从不同种类的元素创建统一的按钮inputbuttona元素创建 jQuery UI 按钮Ten
创建切换按钮从复选框创建 jQuery UIEleven
创建按钮集使用buttonset方法12, 13
创建 jQuery UI 进度条使用progressbar方法14, 15
获取或设置向用户显示的进度使用value方法Sixteen
响应进度条中的更改指定createchangecomplete事件的功能Seventeen
创建 jQuery UI 滑块使用slider方法Eighteen
更改 jQuery UI 滑块的方向使用orientation设置19, 20
当用户单击滑块时,动画显示手柄的移动使用animate设置Twenty-one
创建一个 jQuery UI 滑块,允许用户指定值的范围使用rangevalues设置Twenty-two
以编程方式控制 jQuery UI 滑块使用valuevalues方法Twenty-three
响应滑块手柄位置的变化处理startstopchangeslide事件Twenty-four

自上一版以来,JQUERY UI 发生了变化

从 jQuery UI 1.10 开始,progress 小部件可以用来显示不确定的任务。有关详细信息和示例,请参见“使用 jQuery UI 进度条”一节。

使用 jQuery UI 按钮

我看到的第一个小部件很好地介绍了 jQuery UI 的世界。button 小部件很简单,但是对 HTML 文档有一种转换效果。按钮小部件将 jQuery UI 主题应用于buttona元素。这意味着元素的大小、形状、字体和颜色被转换以匹配我在第十七章中创建自定义 jQuery UI 下载时选择的主题。应用 jQuery UI 小部件很简单,如清单 18-1 所示。

清单 18-1 。一个简单的 HTML 文档

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="handlebars.js"></script>
    <script src="handlebars-jquery.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <link rel="stylesheet" type="text/css" href="styles.css"/>

    <script id="flowerTmpl" type="text/x-handlebars-template">
        {{#flowers}}
        <div class="dcell">
            <img src="{{product}}.png"/>
            <label for="{{product}}">{{name}}:</label>
            <input name="{{product}}" data-price="{{price}}" data-stock="{{stocklevel}}"
                value="0" required />
        </div>
        {{/flowers}}
    </script>

    <script type="text/javascript">
        $(document).ready(function () {
            $.ajax("mydata.json", {
                success: function (data) {
                    var tmplData = $("#flowerTmpl")
                        .template({ flowers: data }).filter("*");
                    tmplData.slice(0, 3).appendTo("#row1");
                    tmplData.slice(3).appendTo("#row2");
                }
            });

            $("button").button();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="oblock">
            <div class="dtable">
                <div id="row1" class="drow">
                </div>
                <div id="row2"class="drow">
                </div>
            </div>
        </div>
        <div id="buttonDiv"><button type="submit">Place Order</button></div>
    </form>
</body>
</html>

为了应用 button 小部件,我使用 jQuery 选择我想要转换的元素,并调用button方法;jQuery UI 负责剩下的工作。你可以在图 18-1 中看到效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-1 。应用按钮小部件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示注意,我将button方法应用于 jQuery 选择对象。jQuery 和 jQuery UI 之间的集成非常紧密,这意味着使用 jQuery UI 通常是我在本书前面向您展示的核心 jQuery 技术的自然扩展。

像所有 jQuery UI 小部件一样,图中显示的按钮是应用于现有 HTML 元素的一系列 CSS 样式。button方法像这样转换一个元素

<button type="submit">Place Order</button>

对此

<button type="submit" class="ui-button ui-widget ui-state-default ui-corner-all
    ui-button-text-only" role="button" aria-disabled="false">
        <span class="ui-button-text">Place Order</span>
</button>

这是一个很好的方法,因为它围绕标准的 HTML 元素工作,这意味着在创建 HTML 内容时,您不必为 jQuery UI 做任何特殊的准备。

配置按钮

jQuery UI 按钮小部件可以通过设置属性进行配置,允许控制创建按钮的方式。表 18-2 描述了这些属性。

表 18-2 。按钮小工具的设置属性

财产描述
disabled获取或设置按钮的禁用状态。true值表示按钮被禁用。jQuery UI 不考虑底层 HTML 元素的状态。
text获取或设置按钮是否显示文本。如果icons属性为false,则忽略该设置。
icons获取或设置按钮是否显示图标。
label获取或设置按钮显示的文本。

这些设置有两种应用方式。第一个是在调用button方法时使用 map 对象,如清单 18-2 中所强调的。

清单 18-2 。使用地图对象配置按钮微件

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("button").button({
            label: "Place Your Order",
            disabled: true
        });

        $("button").button("option", "disabled", false);
    });
</script>
...

我已经用label属性设置了按钮显示的文本,并使用disabled属性禁用了按钮。使用地图对象是定义小部件初始配置的方法,并遵循你最近在第十五章中看到的配置 Ajax 请求的风格。

清单 18-2 还展示了在创建小部件后改变设置属性值的技术,如下所示:

...
$("button").button("option", "disabled", false);
...

我再次调用button方法,但是这次有三个参数。第一个参数是字符串option,它告诉 jQuery UI 我想更改一个设置。第二个参数是我想要更改的设置,第三个参数是设置的新值。这条语句将disabled设置为false,启用按钮并更改我在创建小部件时用地图对象设置的值。

您可以将这些技术结合起来,这样就可以用第一个参数option和第二个参数 map 对象来调用button方法。这允许你一次改变多个设置,如清单 18-3 所示。

清单 18-3 。对地图对象使用选项参数

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("button").button();

        $("button").button("option", {
            label: "Place Your Order",
            disabled: false
        });

        console.log("Disabled: " + $("button").button("option", "disabled"));
    });
</script>
...

你也可以使用同样的技术让读取一个设置的值。在这种情况下,您调用只有两个参数的button方法。第一个是字符串option,第二个是要读取其值的设置的名称,如清单中的以下语句所示:

...
console.log("Disabled: " + $("button").button("option", "disabled"));
...

以这种方式使用时,button方法返回当前设置值。示例语句读取disabled设置的值,并将其写入控制台,产生以下输出:

Disabled: false

在按钮中使用 jQuery UI 图标

jQuery UI 主题包括一组可以用于任何目的的图标,包括在按钮中显示它们。清单 18-4 显示了图标在 jQuery UI 按钮中的使用。

清单 18-4 。在按钮中显示图标

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("button").button({
            icons: {
                primary: "ui-icon-star",
                secondary: "ui-icon-circle-arrow-e"
            }
        });
    });
</script>
...

属性指定将显示哪些图标。按钮部件有两个图标位置。primary图标显示在文本的左侧,而secondary图标显示在文本的右侧,两者都由地图对象指定。您可以省略任一属性,只在其中一个位置显示图标。图标本身很小,正如你在图 18-2 中看到的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-2 。在按钮中显示图标

图标是使用 jQuery UI CSS 文件中定义的类来指定的。有 173 种不同的图标可用,太多了,无法在此列出。找出你想要的图标名称的最简单的方法是进入http://jqueryui.com,选择主题页面并向下滚动页面。你会看到所有的图标都列在一个网格中,在每个图标上移动鼠标按钮会显示图标的类名,如图 18-3 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-3 。jQuery UI 图标网格

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在网页上弹出的名字有一个前导句点,必须省略才能与图标设置一起使用。所以,举例来说,如果鼠标悬停在网格中的第一个图标上,就会弹出.ui-icon-caret-1-n。要将此图标与按钮一起使用,请将 primary 或 secondary 属性设置为ui-icon-caret-1-n

使用自定义图像

我觉得 jQuery UI 图标没什么用,因为它们通常太小,不符合我的需求。幸运的是,有两种替代技术可以在 jQuery UI 按钮中显示自定义图像。

第一种方法是在打算应用 jQuery UI 按钮小部件的button元素中插入一个img元素。jQuery UI 按钮小部件尊重底层button元素的内容,并且——只要您使用透明背景的图像——您就不必担心使图像与主题相匹配。清单 18-5 给出了一个简单的演示。

清单 18-5 。使用带有 jQuery UI 按钮的自定义图像

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("button")
            .text("")
            .append("<img src=rightarrows.png width=100 height=30 />")
            .button();
    });
</script>
...

因为我既不想要文本也不想要 jQuery UI 图标,所以我使用 jQuery text方法将内容设置为空字符串。然后我使用append方法将一个img元素插入到button元素中,最后调用button方法来应用 jQuery UI。你可以在图 18-4 中看到结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-4 。在按钮中显示自定图像

使用按钮方法

jQuery UI 小部件还定义了在小部件创建后用来控制它的方法。这些方法有点奇怪,因为您调用相同的 JavaScript 方法,但是传入不同的参数值来改变 jQuery UI 行为。然而,这些仍然被 jQuery UI 团队称为方法,我也这样称呼它们。表 18-3 显示了你可以在按钮部件上使用的不同的 jQuery UI 方法以及每种方法的效果。

表 18-3 。按钮方法

方法描述
button("destroy")将 HTML 元素返回到其原始状态
button("disable")禁用了按钮
button("enable")启用按钮
button("option")设置一个或多个选项;请参见“配置按钮”一节
button("refresh")刷新按钮;请参见“刷新 jQuery UI 按钮的状态”一节

移除小组件

destroy方法从 HTML button元素中移除 jQuery UI 按钮小部件,将其恢复到原始状态,如清单 18-6 所示。

清单 18-6 。使用销毁方法

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("button").button().click(function (e) {
            $("button").button("destroy");
            e.preventDefault();
        });
    });
</script>
...

在清单 18-6 的中,我使用标准的 jQuery click方法为button元素注册了一个处理函数。这是我在第九章中演示的处理事件的技术,不需要调整来支持 jQuery UI。清单中的click处理函数意味着点击按钮从按钮元素中移除 jQuery UI 小部件,如图 18-5 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-5 。销毁 jQuery UI 按钮小部件

启用和禁用按钮

enabledisable方法改变 jQuery UI 按钮的状态,如清单 18-7 所示。

清单 18-7 。启用和禁用按钮

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("<span>Enabled:<span><input type=checkbox checked />").prependTo("#buttonDiv");
        $(":checkbox").change(function (e) {
            $("button").button(
                $(":checked").length == 1 ? "enable" : "disable"
            )
        });

        $("button").button();
    });
</script>
...

我在文档中插入了一个复选框,并使用change方法注册了一个函数,当复选框被选中或未选中时,将调用这个函数。我调用enabledisable方法来改变按钮的状态以匹配复选框。你可以在图 18-6 中看到效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-6 。启用和禁用 jQuery UI 按钮

刷新 jQuery UI 按钮的状态

refresh方法更新 jQuery UI 按钮小部件的状态,以反映底层 HTML 元素的变化。这在你修改代码中其他地方的元素时会很有用,如清单 18-8 所示。

清单 18-8 。刷新 jQuery UI 按钮

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("<span>Enabled:<span><input type=checkbox checked />").prependTo("#buttonDiv");
        $(":checkbox").change(function (e) {
            var buttons = $("button");
            if ($(":checked").length == 1) {
                buttons.removeAttr("disabled");
            } else {
                buttons.attr("disabled", "disabled");
            }
            buttons.button("refresh");
        });

        $("button").button();
    });
</script>
...

在这个例子中,我使用复选框来触发从支撑按钮小部件的 HTML button元素中添加和删除disabled属性。jQuery UI 不会自动检测到这种变化,所以我调用了refresh方法来使一切恢复同步。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示您可能想知道为什么我不直接使用 jQuery UI enabledisable方法,但是清单 18-8 中的场景出奇地常见,因为 jQuery UI 经常在开发过程的后期应用于 HTML 内容,经常用于改进现有的 web 应用。在这种情况下,HTML 元素将由 jQuery UI 用户之前的代码生成和操作,并且不知道将使用按钮小部件,因此能够更新小部件的状态以反映底层 HTML 元素的状态是一个重要的特性。

使用按钮事件

除了底层 HTML 元素的事件之外,jQuery UI 小部件还定义了事件。button小部件定义了一个名为create的事件,当您创建一个 jQuery UI 按钮小部件时会触发该事件。jQuery UI 事件的处理程序是通过将一个 JavaScript map 对象传递给小部件的 jQuery UI 方法来定义的,在本例中是button,如清单 18-9 所示。

清单 18-9 。使用 jQuery UI 按钮创建事件

...
<script type="text/javascript">
    $(document).ready(function () {
        $.ajax("mydata.json", {
            success: function (data) {
                var tmplData = $("#flowerTmpl")
                    .template({ flowers: data }).filter("*");
                tmplData.slice(0, 3).appendTo("#row1");
                tmplData.slice(3).appendTo("#row2");
            }
        });

        $("button").button({
            create: function (e) {
                $(e.target).click(function (e) {
                    alert("Button was pressed");
                    e.preventDefault();
                })
            }
        });
    });
</script>
...

在清单 18-9 中,我使用create事件来设置一个函数来响应button上的click事件。我觉得create事件没什么用处,通常我发现任何可以响应这个事件的事情都可以用一种更符合更广泛的 jQuery 方法的方式来完成。

创建不同类型的按钮

jQuery UI 按钮小部件对它所应用的元素种类很敏感。当您对button元素、或者a元素、或者类型被设置为submitresetbuttoninput元素调用button方法时,会创建一个常规按钮的基本行为。清单 18-10 显示了所有这些被转换成 jQuery UI 按钮的元素。

清单 18-10 。创建标准按钮

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-1.7.js" type="text/javascript"></script>
    <script src="jquery-ui-1.8.16.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.8.16.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function() {
            $(".jqButton").click(function(e) {
               e.preventDefault();
               $(this).button();
            });
        });
    </script>
</head>
<body>
    <form>
        <input class="jqButton" type="submit" id="inputSubmit" value="Submit">
        <input class="jqButton" type="reset" id="inputReset" value="Reset">
        <input class="jqButton" type="button" id="inputButton" value="Input Button">
        <button class="jqButton">Button Element</button>
        <a class="jqButton" href="[`apress.com`](http://apress.com)">A Element</a>
    </form>
</body>
</html>

我已经定义了我所描述的每一种 HTML 元素。我使用了click方法,以便每个元素在被单击时都被转换成一个 jQuery UI 按钮小部件。你可以在图 18-7 中看到这种转变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-7 。创建标准 jQuery UI 按钮

创建切换按钮

如果在类型设置为checkboxinput元素上调用button方法,就会得到一个切换按钮小部件。当您单击切换按钮时,它会根据底层 HTML 元素的选中和未选中状态打开或关闭。清单 18-11 提供了一个演示。

清单 18-11 。将 jQuery UI 应用于复选框

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $(".jqButton").button();
        });
    </script>
</head>
<body>
    <form>
        <input class="jqButton" type="checkbox" id="toggle">
        <label for="toggle">Toggle Me</label>
    </form>
</body>
</html>

要从复选框创建 jQuery UI 按钮,必须有一个input元素和一个匹配的label元素,如清单所示。jQuery UI 创建了一个按钮,它与基本按钮具有相同的外观,但是在单击时会切换其状态。你可以在图 18-8 中看到效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-8 。从复选框创建切换按钮

请记住,jQuery UI 不会改变底层的 HTML 元素,所以当复选框包含在表单中时,浏览器仍然会以同样的方式处理它。使用checked属性反映状态的变化,就像没有 jQuery UI 一样。

创建按钮集

您可以使用buttonset方法从单选按钮元素创建 jQuery UI 按钮,如清单 18-12 中的所示。

清单 18-12 。创建按钮集

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#radioDiv").buttonset();
        });
    </script>
</head>
<body>
    <form>
        <div id="radioDiv">
            <input type="radio" name="flower" id="rose" checked />
            <label for="rose">Rose</label>
            <input type="radio" name="flower" id="lily"/><label for="lily">Lily</label>
            <input type="radio" name="flower" id="iris"/><label for="iris">Iris</label>
        </div>
    </form>
</body>
</html>

注意,我选择了包含单选按钮的div元素,以便调用buttonset方法:您不需要在单个input元素上调用button方法。你可以在图 18-9 的中看到buttonset方法的效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-9 。创建按钮集

最多只能选择按钮集中的一个按钮,这允许您以与其他 jQuery UI 按钮在视觉上一致的方式为用户提供一组固定的选项。请注意,jQuery UI 通过将不同的样式应用到按钮相遇的边缘,强调了一组按钮之间的关系。这在图 18-10 中显示得更清楚。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-10 。按钮集的 jQuery UI 样式

从常规按钮创建按钮集

您可以在任何可以与常规的button方法一起使用的元素上使用buttonset方法。这具有应用一组单选按钮的样式但是而不是行为的效果,以便每个按钮单独工作。清单 18-13 展示了buttonset方法的这种用法。

清单 18-13 。从常规按钮创建按钮集

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#radioDiv").buttonset();
        });
    </script>
</head>
<body>
    <form>
        <div id="radioDiv">
            <input type="submit" value="Submit"/>
            <input type="reset" value="Reset"/>
            <input type="button" value="Press Me"/>
            <a href="[`apress.com`](http://apress.com)">Visit Apress</a>
        </div>
    </form>
</body>
</html>

div容器中任何合适的元素都将被转换成一个按钮,相邻的边缘将被设计成单选按钮的样式,如图 18-11 中的所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-11 。从常规按钮创建按钮集

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示使用这种技巧时要小心。这可能会让用户感到困惑,尤其是当您在同一文档或 web 应用的其他地方使用单选按钮时。

使用 jQuery UI 进度条

现在我已经使用按钮探索了 jQuery UI 小部件的基本结构,接下来我将看看 jQuery UI 支持的其他小部件,从进度条开始。

进度条允许您向用户显示完成任务的进度。进度条被设计用来显示确定性任务,在这里你可以给用户一个精确的指示,以百分比表示你完成任务的进度,以及不确定性任务,在这里进度的百分比目前是未知的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示jQuery UI 在 1.10 版本中增加了显示不确定任务的支持。有关此功能的详细信息,请参见“创建不确定的进度条”一节。

显示有用的进度信息

web 应用中应该如何使用窗口小部件没有规则,但是用户对进度条等控件的期望是由 Windows 和 Mac OS 等操作系统设定的标准决定的。为了帮助用户理解你的进度条,有一些规则要遵循。

首先,只增加进度。当任务的步骤比最初预期的多时,不要试图降低进度。进度条显示任务已完成的百分比,而不是剩余时间的估计值。如果一项任务有不同的可能路径,那么显示最悲观的进度。与其让用户困惑,不如在进程中取得巨大的进步。

第二,不要在进度条上循环不止一次。如果您有足够的信息向用户显示相当准确的完成信息,那么您应该使用不确定的进度指示器。当进度接近 100%时,用户希望任务完成。如果进度条随后重置,并开始再次建立,你只是混淆了用户,使进度条的使用毫无意义。

创建进度条

你通过选择一个div元素并调用progressbar方法来创建一个进度条,如清单 18-14 所示。

清单 18-14 。创建进度条

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#progressDiv").progressbar({
                value: 21
            });
        });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
</body>
</html>

该文档包含一个div元素,其idprogressDiv。要创建一个进度条,我必须使用一个空的div元素——如果div元素有任何内容,它将影响进度条的布局。我使用 jQuery 选择progressDiv元素并调用 jQuery UI progressbar方法,传入一个 map 对象来提供初始配置。进度条支持三种设置,我已经在表 18-4 中描述过。

表 18-4 。进度条小工具的设置

环境描述
disabled如果true,进度条将被禁用。默认值为false
value设置向用户显示的完成百分比。默认值为零。将属性设置为false以显示不确定的进度条,如“创建不确定的进度条”一节所述
max设置进度条将显示的最大值。默认为100

在这个例子中,我指定了一个初始值 21(由于我没有改变max设置的值,这个值相当于 21%),你可以在图 18-12 中看到这个效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-12 。创建进度条

创建不确定的进度条

从 jQuery UI 1.10 开始,jQuery UI 进度条小部件支持显示不确定任务的进度,这是通过将value配置属性设置为false而不是指定一个数值来配置的,如清单 18-15 所示。

清单 18-15 。创建不确定的进度条

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <script type="text/javascript">
        $(document).ready(function () {
            $("#progressDiv").progressbar({
                value: false
            });
        });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
</body>
</html>

jQuery UI 显示一个不确定的进度,一个简单的动画应用于整个工具条。你需要运行这个例子来看看动画的效果,但是图 18-13 显示的是一帧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-13 。创建不确定的进度条

使用进度条方法

进度条小部件定义了许多方法,这些方法与按钮的样式相同。换句话说,您调用 JavaScript progressbar方法,第一个参数指定您想要的 jQuery UI 小部件方法。表 18-5 描述了可用的方法。

表 18-5 。进度条方法

方法描述
progressbar("destroy")div元素返回到其原始状态
progressbar("disable")禁用了进度条
progressbar("enable")启用进度条
progressbar("option")设置一个或多个选项;有关配置 jQuery UI 小部件的详细信息,请参见“配置按钮”一节
progressbar("value", value)获取和设置进度栏显示的值,并在不确定进度栏和确定进度栏之间切换

这些方法中的大部分都以与按钮部件相同的方式工作,所以我不打算再次演示它们。例外是value方法,它允许您获取和设置进度条显示的值,并在确定和不确定状态之间切换。清单 18-16 展示了价值方法的使用。

清单 18-16 。使用进度条值方法

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
     <script type="text/javascript">
         $(document).ready(function () {

             $("#progressDiv").progressbar({
                 value: 21
             });

             $("button").click(function (e) {
                 var divElem = $("#progressDiv");
                 if (this.id == "mode") {
                     divElem.progressbar("value", false);
                 } else {
                     var currentProgress = divElem.progressbar("value");
                     if (!currentProgress) {
                         divElem.progressbar("value", 21);
                     } else {
                         divElem.progressbar("value",
                             this.id == "decr" ? currentProgress - 10 :
                                                     currentProgress + 10)
                     }
                 }
             });
         });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
    <button id="decr">Decrease</button>
    <button id="incr">Increase</button>
    <button id="mode">Indeterminate</button>
</body>
</html>

我在这个例子中添加了button元素。我用它们来增加或减少进度条显示的值,并在确定和不确定模式之间切换。每按一次DecreaseIncrease按钮,数值变化 10%,如图 18-14 中所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-14 。使用数值方法更改显示的进度

Indeterminate按钮调用value方法将进度条切换到中间模式。点击其他按钮将设置一个数字value,这将使进度条回到确定的模式,如图 18-15 中的所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-15 。更改进度条的模式

使用进度条事件

jQuery UI 进度条小部件定义了三个事件,如表 18-6 中所述。

表 18-6 。进度条事件

事件描述
create创建进度条时触发
change当进度栏的值改变时触发
complete当进度条的值设置为 100 时触发

清单 18-17 显示了正在使用的事件。

清单 18-17 。使用进度条事件

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
     <script type="text/javascript">
         $(document).ready(function () {

             $("button").button();

             $("#progressDiv").progressbar({
                 value: 21,
                 create: function (e) {
                     $("#progVal").text($("#progressDiv").progressbar("value"));
                 },
                 complete: function (e) {
                     $("#incr").button("disable")
                 },
                 change: function (e) {
                     var currentValue = $("#progressDiv").progressbar("value");
                     if (!currentValue) {
                         $("#progWrapper").hide();
                     } else {
                         if ($(this).progressbar("value") < 100) {
                             $("#incr").button("enable")
                         }
                         $("#progVal").text(currentValue);
                         $("#progWrapper").show();
                     }
                 }
             });

             $("button").click(function (e) {
                 var divElem = $("#progressDiv");
                 if (this.id == "mode") {
                     divElem.progressbar("value", false);
                 } else {
                     var currentProgress = divElem.progressbar("value");
                     if (!currentProgress) {
                         divElem.progressbar("value", 21);
                     } else {
                         divElem.progressbar("value",
                             this.id == "decr" ? currentProgress - 10 :
                                                     currentProgress + 10)
                     }
                 }
             });
         });
    </script>
</head>
<body>
    <div id="progressDiv"></div>
    <button id="decr">Decrease</button>
    <button id="incr">Increase</button>
    <button id="mode">Indeterminate</button>
    <span id="progWrapper">Progress: <span id="progVal"></span>%</span>
</body>
</html>

在清单 18-17 中,当进度条处于确定模式时,我使用span元素来显示数字进度值。我使用create事件来显示初始值,该值是使用value配置属性设置的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示注意,我已经为进度条的设置和事件使用了相同的地图对象。这不是必需的,但是它允许我在一次方法调用中创建和配置一个小部件。

我使用complete事件在进度到达100%时禁用Increase按钮,并使用change事件确保按钮对其他值启用,显示当前值并在确定和不确定模式之间切换。你可以在图 18-16 中看到效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-16 。响应进度条事件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在使用事件时,有一些事情需要记住。首先,每当value被设置为 100 或更大时,就会触发complete事件。例如,这意味着如果您重复将该值设置为 100,该事件可能会触发多次。其次,changecomplete事件都是为 100 或更大的值触发的,所以当您完成进度更新时,您必须能够处理这两个事件。

使用 jQuery UI 滑块

顾名思义,滑块小部件在 HTML 文档中的一个元素外创建一个滑块,并允许用户选择一个值,而不必在input元素中输入文本。使用slider方法将 slider 小部件应用于 HTML 元素,如清单 18-18 所示。

清单 18-18 。创建滑块

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #slider { margin: 10px; }
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#slider").slider();
         });
    </script>
</head>
<body>
    <div id="slider"></div>
</body>
</html>

滑块的主题与其他 jQuery UI 小部件一致,并允许用户使用鼠标或箭头键来上下移动滑块手柄。你可以在图 18-17 中看到基本滑块的样子。(注意,在这个例子中,我为支撑滑块的元素定义了一个 CSS 样式——如果没有这个样式,滑块将紧靠其父元素的边缘显示。)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-17 。一个基本的 jQuery UI 滑块

配置滑块

对于所有的 jQuery UI 小部件,slider 小部件定义了许多设置,您可以使用这些设置来配置滑块的外观和行为。表 18-7 描述了这些设置,我将在接下来的章节中向你展示如何使用这些设置来配置小工具。

表 18-7 。滑块小工具的设置

环境描述
animatetrue时,当用户点击手柄外的位置时,动画显示滑块。默认为false
disabled设置为true时禁用滑块。默认为false
max定义滑块的最大值。默认为100
min定义滑块的最小值。默认为0
orientation定义滑块的方向;详见清单 18-19 。
rangevalues设置一起使用,创建多手柄滑块。
step定义滑块在minmax值之间移动的间隔。
value定义滑块表示的值。
values与 range 设置一起使用,创建多手柄滑块。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示minmax的值是独占的,也就是说如果你设置了0min值和100max值,用户可以在199之间选择值。

更改滑块方向

默认情况下,滑块是水平的,但是你也可以使用orientation设置来创建垂直滑块,如清单 18-19 中的所示。

清单 18-19 。使用方向设置

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #hslider, #vslider { margin: 10px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#hslider").slider({
                 value: 35
             });

             $("#vslider").slider({
                 orientation: "vertical",
                 value: 35
             });
         });
    </script>
</head>
<body>
    <div id="hslider"></div>
    <div id="vslider"></div>
</body>
</html>

我创建了两个滑块,其中一个的orientation设置为vertical。我还改变了style元素,这样我就可以给滑块元素加一个边距,让它们分开。您通过设计底层元素的样式来控制滑块(以及任何 jQuery UI 小部件)的大小和位置(这就是为什么div元素工作得最好;它们可以很容易地用 CSS 来操作)。您可以在图 18-18 中看到滑块。注意,我使用了value设置来设置手柄的初始位置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-18 。创建垂直和水平滑块

尽管我将选项和方法分开,但我可以用不同的方式编写清单 18-19 来更好地利用底层的 jQuery 功能,如清单 18-20 中的所示。

清单 18-20 。更好地利用 jQuery

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #hslider, #vslider { margin: 10px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#hslider, #vslider").slider({
                 value: 35,
                 orientation: "vertical"
             }).filter("#hslider").slider("option", "orientation", "horizontal");
         });
    </script>
</head>
<body>
    <div id="hslider"></div>
    <div id="vslider"></div>
</body>
</html>

这是一个小问题,但是我不希望您忘记 jQuery UI 是建立在 jQuery 之上的,并且与 jQuery 紧密集成,您可以使用在本书前面看到的所有选择和操作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示注意,我将初始方向设置为vertical,然后将其更改为horizontal。滑块有一个错误,在滑块创建后将方向改为vertical会导致手柄错位。

制作滑块动画

animate设置使得当用户在他希望手柄移动到的点点击滑块时,手柄能够平滑移动(与通过拖动滑块来设置值相反)。您可以通过将animate设置为true来启用默认动画,通过使用fastslow来设置动画的速度,或者指定动画应该持续的毫秒数。清单 18-21 显示了animate设置的使用。

清单 18-21 。使用动画设置

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-1.7.js" type="text/javascript"></script>
    <script src="jquery-ui-1.8.16.custom.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.8.16.custom.css"/>
    <style type="text/css">
        #slider {margin: 10px}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#slider").slider({
                animate: "fast"
            });
        });
    </script>
</head>
<body>
    <div id="slider"></div>
</body>
</html>

我已经将animate设置为fast。很难在截图中显示动画,但是图 18-19 显示了animate设置的作用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-19 。制作手柄运动的动画

这个截图显示了我点击鼠标按钮之前的滑块。如果我没有启用动画,那么句柄将会捕捉到我单击的位置,立即为滑块设置新的值。但是由于我已经启用了动画,滑块会以一种不那么不和谐的方式优雅地移动到它的新位置。然而,像任何效果或动画一样,我不想过度渲染效果,这就是为什么我选择了fast选项。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示这是一个例子,您需要使用它来查看完整的结果。如果你不想输入代码和 HTML,你可以在 Apress 网站的源代码/下载区找到本章的代码样本。它可以从apress.com免费获得,包含了本书中的所有例子。

创建范围滑块

范围滑块有两个手柄,让用户指定一个范围的值,而不是单个值。例如,您可能希望让用户表达她愿意为产品支付的价格范围,以便您可以过滤掉其他任何内容。清单 18-22 演示了如何创建一个范围滑块。

清单 18-22 。创建范围滑块

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #slider {margin: 20px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#slider").slider({
                 values: [35, 65],
                 range: true,
                 create: displaySliderValues,
                 slide: displaySliderValues
             });

             function displaySliderValues() {
                 $("#lower").text($("#slider").slider("values", 0));
                 $("#upper").text($("#slider").slider("values", 1));
             }
         });
    </script>
</head>
<body>
    <div id="slider"></div>
    <div>Lower Value: <span id="lower">
    </span> Upper Value: <span id="upper"></span></div>
</body>
</html>

要创建一个范围滑块,必须将range设置为true,并将值setting设置为一个数组,该数组包含范围的初始下限和上限。(使用常规滑块时,使用value设置,使用范围滑块时,使用values设置。)在这个例子中,我将界限设置为 35 和 65。你可以在图 18-20 中看到效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-20 。创建范围滑块

我为createslide事件添加了一个处理函数。我将在“使用滑块事件”一节中讨论滑块支持的事件,但是我想演示如何获得范围滑块中手柄的位置。您可以通过values方法,指定您感兴趣的滑块的索引,如下所示:

...
$("#slider").slider("values", 0);
...

索引是从零开始的,因此该语句获取代表范围下限的句柄值。我使用事件来设置两个span元素的内容。

使用滑块方法

滑块定义了所有 jQuery UI 小部件定义的相同的一组基本方法,还定义了几个允许您设置单个值或要显示的值范围的方法。表 18-8 描述了这些方法。

表 18-8 。滑块方法

方法描述
slider("destroy")将基础元素返回到其原始状态
slider("disable")禁用滑块
slider("enable")启用滑块
slider("option")设置一个或多个选项;有关配置 jQuery UI 小部件的详细信息,请参见“配置按钮”一节
slider("value", value)获取或设置常规滑块的值
slider("values", [values])获取或设置范围滑块的值

清单 18-23 展示了如何使用valuevalues方法以编程方式控制滑块。

清单 18-23 。以编程方式控制滑块

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #slider, #rangeslider, *.inputDiv { margin: 10px}
        label {width: 80px; display: inline-block; margin: 4px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {

             $("#slider").slider({
                 value: 50,
                 create: function () {
                     $("#slideVal").val($("#slider").slider("value"));
                 }
             });

             $("#rangeslider").slider({
                 values: [35, 65],
                 range: true,
                 create: function () {
                     $("#rangeMin").val($("#rangeslider").slider("values", 0));
                     $("#rangeMax").val($("#rangeslider").slider("values", 1));
                 }
             })

             $("input").change(function (e) {
                 switch (this.id) {
                     case "rangeMin":
                     case "rangeMax":
                         var index = (this.id == "rangeMax") ? 1 : 0;
                         $("#rangeslider").slider("values", index, $(this).val())
                         break;
                     case "slideVal":
                         $("#slider").slider("value", $(this).val())
                         break;
                 }
             })
         });
    </script>
</head>
<body>
    <div id="rangeslider"></div>
    <div class="inputDiv">
        <label for="rangeMin">Range Min: </label><input id="rangeMin" />
        <label for="rangeMax">Range Max: </label><input id="rangeMax" />
    </div>
    <div id="slider"></div>
    <div class="inputDiv">
        <label for="slideVal">Slide Val: </label><input id="slideVal" />
    </div>
</body>
</html>

该文档包含两个滑块和三个input元素,允许在不移动手柄本身的情况下指定手柄的值。你可以在图 18-21 的中看到元件的布局。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-21 。以编程方式控制滑块

我使用 jQuery 来选择input元素,并调用change方法来为change事件设置一个处理程序,这意味着每当input元素之一的值发生变化时,就会调用该函数。

在处理函数中,我使用触发事件的元素的id属性来判断我需要操作哪个滑块,并调用valuevalues方法来设置句柄位置。input元素和滑块之间的关系是单向的,这意味着移动手柄不会更新input元素。在下一节中,我将向您展示如何创建双向关系。

使用滑块事件

表 18-9 显示了滑块支持的事件。这些事件最好的特性是同时支持changestop,这允许您区分用户移动句柄所创建的新值和您以编程方式设置的值。

表 18-9 。滑块事件

事件描述
create创建滑块时触发
start当用户开始滑动手柄时触发
slide手柄滑动时,每次鼠标移动都会触发
change当用户停止滑动手柄或以编程方式更改值时触发
stop当用户停止滑动手柄时触发

清单 18-24 展示了使用滑块事件在滑块和input元素之间创建双向关系,类似于上一节中的例子,尽管为了保持例子简单,我已经删除了其中一个滑块。这种双向关系允许我将编程支持和用户交互结合起来管理滑块。

清单 18-24 。使用滑块事件在滑块和输入之间创建双向关系

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js"></script>
    <script src="jquery-ui-1.10.3.custom.js"></script>
    <link href="jquery-ui-1.10.3.custom.css" rel="stylesheet" />
    <style>
        #rangeslider, *.inputDiv { margin: 10px}
        label {width: 80px; display: inline-block; margin: 4px}
    </style>
     <script type="text/javascript">
         $(document).ready(function () {
             $("#rangeslider").slider({
                 values: [35, 65],
                 range: true,
                 create: setInputsFromSlider,
                 slide: setInputsFromSlider,
                 stop: setInputsFromSlider
             });

             function setInputsFromSlider() {
                 $("#rangeMin").val($("#rangeslider").slider("values", 0));
                 $("#rangeMax").val($("#rangeslider").slider("values", 1));
             }

             $("input").change(function (e) {
                 var index = (this.id == "rangeMax") ? 1 : 0;
                 $("#rangeslider").slider("values", index, $(this).val())
             });
         });
    </script>
</head>
<body>
    <div id="rangeslider"></div>
    <div class="inputDiv">
        <label for="rangeMin">Range Min: </label><input id="rangeMin" />
        <label for="rangeMax">Range Max: </label><input id="rangeMax" />
    </div>
</body>
</html>

在这个例子中,我处理了createslidestop事件。现在,当向输入元素中输入新值时,滑块手柄会移动,当滑块移动时,输入元素中的值也会更新。你可以在图 18-22 中看到文档的样子,但这是一个需要交互才能看到完整效果的例子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 18-22 。响应滑块事件

摘要

在本章中,我向您介绍了前三个 jQuery UI 小部件:按钮、进度条和滑块。每个小部件都遵循相同的基本结构:有一个方法可以创建和配置小部件,并让您提供响应其事件的函数。有些方法和事件是每个小部件共有的,但也有一些独特的附加功能,它们揭示了一些小部件提供的特殊功能。现在我已经有了基本的方法,我将在接下来的章节中向您展示一些更加灵活和复杂的小部件。在第十九章中,我向你展示了自动完成和折叠部件。

十九、使用自动完成和折叠部件

在本章中,我将描述 jQuery UI 自动完成和 accordion 小部件。它们比我在第十八章中展示的小部件更复杂,但是它们遵循相同的设置、方法和事件模式。这些是高度可配置的、灵活的、聪明的用户界面控件,如果使用得当,它们可以显著增强文档和 web 应用的外观和可用性。表 19-1 对本章进行了总结。

表 19-1 。章节总结

问题解决办法列表
input元素添加 jQuery UI 自动完成特性使用autocomplete方法1, 2
从远程服务器获取自动完成建议source设置为 URL3–5
动态生成自动完成建议source设置指定一个功能six
从异步任务返回自动完成结果调用response函数seven
控制自动完成弹出窗口的位置使用position属性eight
以编程方式控制自动完成功能使用searchclose方法nine
接收所选自动完成项目的通知使用focusselectchange事件Ten
修改向用户显示的自动完成结果处理response事件Eleven
覆盖默认的自动完成操作覆盖select事件的默认动作Twelve
创建 jQuery UI 折叠小部件使用accordion方法Thirteen
设置折叠面板及其内容面板的高度使用heightStyle设置14–16
更改用户激活内容元素时必须执行的操作使用event设置Seventeen
在 jQuery UI accordion 中设置活动内容元素使用activecollapsible设置18, 19
更改手风琴使用的图标使用icons设置Twenty
当折叠面板中的活动元素更改时接收通知处理activatebeforeactivate事件Twenty-one

自上一版以来,JQUERY UI 发生了变化

在 jQuery UI 1.10 版本中,accordion 小部件的 API 发生了很多变化:配置选项、方法和事件都发生了变化。我在本章的相关章节中列出了这些变化。

我在本章中也描述了 autocomplete 小部件,它有一个有用的新特性:您可以控制为用户提供完成选项的弹出窗口的位置(参见“定位弹出窗口”一节)。

使用 jQuery UI 自动完成

当用户在input元素中输入值时,autocomplete 小部件向用户提供建议。如果使用得当,这个小部件可以为用户节省时间,加快数据输入并减少错误。在接下来的小节中,我将向您展示如何创建、配置和使用 jQuery UI autocomplete 小部件。

创建自动完成元素

您可以在一个input元素上使用autocomplete方法来创建一个自动完成小部件。清单 19-1 演示了如何设置基本的自动完成功能。

清单 19-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"/>
    <script type="text/javascript">
        $(document).ready(function() {

            var flowers = ["Aster", "Daffodil", "Rose", "Peony", "Primula", "Snowdrop",
                           "Poppy", "Primrose", "Petuna", "Pansy"];

            $("#acInput").autocomplete({
                source: flowers
            })
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
</body>
</html>

就像你见过的其他 jQuery UI 方法一样,autocomplete方法被应用于 HTML 元素,并且配置了一个定义了source属性的 map 对象。此属性指定自动完成条目的来源。

您可以为自动完成值使用一系列不同的数据源,我将在本章的后面演示。在清单 19-1 中,我使用了一个简单的值数组。图 19-1 展示了自动完成功能呈现给用户的方式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-1 。一个基本的 jQuery UI 自动完成元素

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意自动完成特性不强制任何类型的验证,用户可以在input元素中输入任何值,而不仅仅是那些由source设置定义的值。

图 19-1 中有两张截图。第一个显示了当我输入字母 P 时会发生什么。如您所见,第一个屏幕截图显示了包含字母 P 的数据项列表。这个列表包括以 P 开头的花名,但也包括雪花莲(因为它包含字母 p )。在第二个截图中,我输入了 Pe ,jQuery UI 只显示包含该字母组合的条目。用户可以继续键入条目或从自动完成列表中选择一个条目。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在文档中,我把input元素和它的label放在一个属于ui-widget类的div元素里面。这将设置labelinput元素的 CSS 字体属性,以匹配自动完成弹出窗口使用的字体属性。我会在第三十五章中解释更多关于如何使用 jQuery UI CSS 类的内容。

使用对象数组作为数据源

另一种方法是使用对象数组,而不是字符串。这允许我将弹出菜单中显示的标签与插入到input元素中的值分开,如清单 19-2 所示。

清单 19-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="jquery-ui-1.10.3.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function() {

            var flowers = [{label: "Aster (Purple)", value: "Aster"},
                {label: "Daffodil (White)", value: "Daffodil"},
                {label: "Rose (Pink)", value: "Rose"},
                {label: "Peony (Pink)", value: "Peony"}]

            $("#acInput").autocomplete({
                source: flowers
            })

        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
</body>
</html>

当使用对象数组时,autocomplete 特性会寻找名为labelvalue的属性。label属性用于创建弹出列表,如果选择了项目,则value条目将被插入到input元素中。在清单 19-2 中,我给标签添加了一些颜色信息,这些信息在标签被选中时不包含在值中,如图图 19-2 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-2 。使用对象数组将标签与值分开

配置自动完成

自动完成功能支持许多设置,让您控制其功能的不同方面,如表 19-2 所述。在接下来的小节中,我将向您展示如何使用这些设置来配置小部件。

表 19-2 。自动完成设置

环境描述
appendTo指定弹出菜单应追加到的元素。默认为body元素。
autoFocus如果设置为true,列表中的第一个项目将获得焦点,这意味着用户可以通过按回车键来选择该项目。默认为false
delay指定击键后的延迟时间(以毫秒为单位),在此之后自动完成数据被更新。默认为300
disabled设置为true时,禁用自动完成功能。这个设置不影响底层的input元素。默认是false
minLength指定在显示自动完成菜单之前,用户必须键入的最少字符数。默认为1
position设置弹出菜单相对于输入元素的位置。
source指定要添加到自动完成菜单中的项目的源。该设置没有默认值,必须在调用autocomplete方法时指定。

使用远程数据源

最有趣的自动完成设置是source,因为您可以使用它来处理各种不同类型的数据,以填充弹出菜单。我在清单 19-2 中使用了一个 JavaScript 数组,这对于简单的静态数据列表来说很好。对于更复杂的情况,您可以从服务器获取匹配项的列表。你所要做的就是指定将生成数据的 URL,如清单 19-3 所示。

清单 19-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="jquery-ui-1.10.3.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function() {

            $("#acInput").autocomplete({
                source: "[`node.jacquisflowershop.com/auto`](http://node.jacquisflowershop.com/auto)"
            })
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
</body>
</html>

当 jQuery UI 需要弹出自动完成菜单的项目列表时,它将向指定的 URL 发出 HTTP GET 请求。使用键term将用户到目前为止键入的字符包含在请求查询字符串中。例如,如果用户输入了字母 s ,那么 jQuery UI 将请求下面的 URL:

http://node.jacquisflowershop.com/auto?term=s

如果用户随后键入字母 n ,jQuery UI 将请求以下内容:

http://node.jacquisflowershop.com/auto?term=sn

当有很多数据项并且您不想将它们都发送给客户端时,这种技术非常有用。当项目列表动态变化,并且您希望确保用户受益于最新的可用数据时,它也很有用。

服务器负责从查询字符串中获取term值,并返回一个 JSON 字符串,表示要显示给用户的项目数组。清单 19-4 展示了我是如何为Node.js脚本更新formserver.js脚本来做到这一点的。(有关获取和安装Node.js的详细信息,请参见第一章。)

清单 19-4 。支持远程自动完成的 Node.js 脚本

var http = require("http");
var querystring = require("querystring");
var url = require("url");

var port = 80;

http.createServer(function (req, res) {
    console.log("[200 OK] " + req.method + " to " + req.url);

    var flowers = ["Aster", "Daffodil", "Rose", "Peony", "Primula", "Snowdrop",
                    "Poppy", "Primrose", "Petuna", "Pansy"];

    var matches = [];
    var term = url.parse(req.url, true).query["term"];

    if (term) {
        var pattern = new RegExp("^" + term, "i");
        for (var i = 0; i < flowers.length; i++) {
            if (pattern.test(flowers[i])) {
                matches.push(flowers[i]);
            }
        }
    } else {
        matches = flowers;
    }

    res.writeHead(200, "OK", {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    });
    res.write(JSON.stringify(matches));
    res.end();

}).listen(port);
console.log("Ready on port " + port);

这个Node.js脚本使用与清单 19-2 中的相同的一组花名,并返回那些与浏览器发送的词语相匹配的花名。我稍微改变了搜索,只返回那些以单词开头的名字。例如,如果 jQuery UI 发送如下请求:

http://node.jacquisflowershop.com/auto?term=p

然后Node.js服务器将返回下面的 JSON:

["Peony","Primula","Poppy","Primrose","Petuna","Pansy"]

因为我是在花名开头匹配,所以列表中省略了雪花莲,如图图 19-3 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-3 。从远程服务器获取自动完成条目

这是一种很好的技术,但是它会对服务器产生很多请求。在我的例子中这不是问题,因为我正在执行一个简单的搜索,我的服务器和浏览器在同一个网络上。但是对于复杂的搜索,在可能遭受延迟的广域网上,服务器上的负载可能成为一个问题。

管理自动完成请求速率的最佳方式是使用minLengthdelay设置。minLength设置指定了在 jQuery UI 向服务器发出自动完成请求之前,用户必须输入的字符数。您可以使用此设置,以便仅在输入几个字符后向服务器请求数据,此时您已经有足够的信息来缩小搜索范围。

delay设置指定了按键后自动完成信息被请求的时间。您可以使用此设置来防止在用户快速键入时发出请求。因此,如果用户键入 sn ,您可以避免点击服务器获取s列表,然后立即再次获取sn列表。通过组合这些设置,您可以减少请求的数量,并在需要时为用户提供指导。清单 19-5 显示了这些设置的用法。

清单 19-5 。使用 delay 和 minLength 设置减少服务器请求

<!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"/>
    <script type="text/javascript">
        $(document).ready(function() {

            $("#acInput").autocomplete({
                source: "http://node.jacquisflowershop.com/auto",
                minLength: 3,
                delay: 1000
            })
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
</body>
</html>

在清单 19-5 中,直到用户输入了三个字符并且在一秒钟内没有输入任何额外的字符,才会向服务器发出初始请求。

使用函数作为数据源

您可以使用函数为自动完成条目创建真正定制的源。您将该函数分配给source设置,每次 autocomplete 特性需要向用户显示项目时都会调用它。清单 19-6 展示了。

清单 19-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="jquery-ui-1.10.3.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function() {

            var flowers = ["Aster", "Daffodil", "Rose", "Peony", "Primula", "Snowdrop",
                            "Poppy", "Primrose", "Petuna", "Pansy"];

            $("#acInput").autocomplete({
                source: function(request, response) {
                    var term = request.term;
                    var pattern = new RegExp("^" + term, "i");

                    var results = $.map(flowers, function(elem) {
                        if (pattern.test(elem)) {
                            return elem;
                        }
                    })
                    response(results);
                }
            })
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
</body>
</html>

两个参数被传递给该函数。第一个参数是一个只有一个名为term的属性的对象。该属性的值是用户输入到input元素中的字符串。第二个参数是一个函数,当您生成了想要显示给用户的自动完成项目列表时,您将调用这个函数。这个函数的参数是一个字符串或对象的数组。

在清单 19-6 中,我复制了来自清单 19-5 的服务器端功能,并且我生成了一个数组,包含那些以指定术语开始的条目。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示我使用 jQuery map工具方法处理了数组的内容,我在第三十四章中对此进行了描述。

然后,我通过将数组作为参数传递给response函数,将结果传递回 jQuery UI,如下所示:

...
response(results);
...

这似乎是一种奇怪的处理结果的方式,但这意味着您可以在异步任务完成后调用该函数。在清单 19-7 中,您可以看到我是如何使用一个函数发出 Ajax 请求来获取花的细节,对返回的内容进行本地搜索,然后调用response函数将最终结果提供给 jQuery UI。

清单 19-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"/>
    <style type="text/css">
        button {margin-bottom: 5px}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#acInput").autocomplete({
                source: function (request, response) {
                    $.getJSON("[`node.jacquisflowershop.com/auto`](http://node.jacquisflowershop.com/auto)",
                        function(flowers) {
                            var term = request.term;
                            var pattern = new RegExp("^" + term, "i");

                            var results = $.map(flowers, function (elem) {
                                if (pattern.test(elem)) {
                                    return elem;
                                }
                            })
                            response(results);
                        });
                }
            })
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>

    </form>
</body>
</html>

在这个例子中,我使用getJSON方法从Node.js服务器获取完整的 flower 值集合。我在本地搜索匹配项,当我有一组建议要呈现给 jQuery UI 时,调用response函数。

定位弹出窗口

默认情况下,允许用户选择一个值的弹出窗口将出现在input元素下面,但是您可以通过设置position属性来改变这一点——尽管这样做的语法有点笨拙。清单 19-8 显示了一个改变位置的例子。

清单 19-8 。更改弹出窗口的位置

<!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"/>
    <style>
        #target { margin-top: 40px; display:inline-block }
    </style>
    <script type="text/javascript">
        $(document).ready(function () {

            var flowers = [{ label: "Aster (Purple)", value: "Aster" },
                { label: "Daffodil (White)", value: "Daffodil" },
                { label: "Rose (Pink)", value: "Rose" },
                { label: "Peony (Pink)", value: "Peony" }]

            $("#acInput").autocomplete({
                source: flowers,
                position: {
                    my: "left top",
                    at: "right bottom+20",
                    of: "#target",
                    collision: "fit"
                }
            })

        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
    <span id="target">Target</span>
</body>
</html>

position属性是用一个对象配置的,该对象为放置弹出窗口的策略的不同方面指定了属性,我已经在表 19-3 的列表中描述了我使用的四个属性。

表 19-3 。自动完成位置属性

名字描述
my指定将用于确定位置的弹出窗口部分(有关可用值范围的详细信息,请参见下文)
at指定弹出窗口相对于目标元素的位置(有关可用值范围的详细信息,请参见下文)
of指定弹出窗口将相对于其定位的目标元素;如果省略,这就是input元素,但是可以指定为HTMLElement、选择器或jQuery对象
collision指定当弹出窗口溢出窗口时应如何调整弹出窗口的位置(表 19-4 显示了该属性的值)

表 19-4 。自动完成位置属性

名字描述
flipjQuery UI 检查更多弹出窗口是否可以显示在由of属性指定的元素的另一侧;将选择显示最多弹出窗口的一侧
fitjQuery UI 将弹出窗口从窗口边缘移开
flipfit结合了flipfit值的行为
none告诉 jQuery UI 不要调整弹出窗口的位置

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示自动完成弹出窗口是使用 jQuery UI position 工具特性放置的,它比我在本章中使用的配置选项更多。更多详情见http://api.jqueryui.com/position

使用指定水平和垂直位置的值设置myat属性,用空格分隔。水平值为leftrightcenter,垂直值为topbottomcenter。您还可以指定相对于某个位置的偏移量,可以是百分比,也可以是像素数。在清单中,您可以看到我已经如下设置了myatof属性:

...
my: "left top",
at: "right bottom+20",
of: "#target",
...

这种组合意味着:将 autocomplete 弹出窗口的左上角放置在 id 为target的元素的右下角下方 20 个像素的位置。你通常不会使用of属性来指定一个元素,因为它破坏了弹出菜单和input元素之间的视觉关联,但是我想证明在弹出菜单的放置上有很大的灵活性,你可以在图 19-4 中看到这些配置属性的效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-4 。配置自动完成弹出窗口的位置

collision属性指定如果弹出窗口不适合可用空间会发生什么。表 19-4 描述了该属性支持的值。

我为collision属性选择了fit值,这意味着 jQuery UI 将移动弹出窗口以适应浏览器窗口,如图图 19-5 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-5 。移动自动完成弹出窗口以适应浏览器窗口的边缘

使用自动完成方法

jQuery UI 自动完成特性支持许多方法,您可以使用这些方法来操作自动完成过程。表 19-5 描述了这些方法。

表 19-5 。自动完成方法

方法描述
autocomplete("close")关闭自动完成菜单
autocomplete("destroy")从 input 元素中删除自动完成功能
autocomplete("disable")禁用自动完成
autocomplete("enable")启用自动完成
autocomplete("option")设置一个或多个选项
autocomplete("search", value)使用指定值显式触发 autocomplete 如果没有提供值参数,则使用input元素的内容

autocomplete 小部件特有的两种方法是searchclose,您可以使用它们显式地开始和结束自动完成过程,如清单 19-9 所示。

清单 19-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"/>
    <style type="text/css">
        button {margin-bottom: 5px}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {

            var flowers = ["Aster", "Daffodil", "Rose", "Peony", "Primula", "Snowdrop",
                            "Poppy", "Primrose", "Petuna", "Pansy"];

            $("#acInput").autocomplete({
                source: flowers
            });

            $("button").click(function(e) {
                e.preventDefault();
                switch (this.id) {
                    case "close":
                        $("#acInput").autocomplete("close");
                        break;
                    case "input":
                        $("#acInput").autocomplete("search");
                        break;
                    default:
                        $("#acInput").autocomplete("search", this.id);
                        break;
                }
            });
        });
    </script>
</head>
<body>
    <form>
        <button id="s">S</button>
        <button id="p">P</button>
        <button id="input">Input Content</button>
        <button id="close">Close</button>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
</body>
</html>

我添加了button元素,并使用 jQuery click方法来设置不同的自动完成方法调用。当标有 SP 的按钮被按下时,我调用search方法,将选择的字母作为搜索值传入。这将触发使用所选字母的自动完成功能,而不考虑输入元素的内容,如图图 19-6 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-6 。使用带有搜索词的搜索方法

如图所示,弹出菜单显示包含按钮字母的条目,即使input元素包含单词hello

Input Content按钮使用input元素中包含的任何字符触发自动完成功能,如图图 19-7 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-7 。使用输入元素的内容进行搜索

最后一个按钮Close调用close方法来关闭弹出菜单。

使用自动完成事件

自动完成功能定义了许多事件,如表 19-6 所述。

表 19-6 。自动完成事件

事件描述
change当值改变后焦点离开input元素时触发
close当弹出菜单关闭时触发
create创建自动完成功能时触发
focus当弹出菜单中的项目获得焦点时触发
open显示弹出菜单时触发
response在搜索完成后、向用户显示结果前触发
search在生成或请求自动完成项目列表之前触发
select从菜单中选择项目时触发

获取所选项目的详细信息

jQuery UI 通过第二个参数(通常称为ui)提供关于事件的附加信息。对于changefocusselect事件,jQuery UI 为ui对象提供了一个item属性,该属性返回一个描述从弹出菜单中选择或聚焦的项目的对象。清单 19-10 展示了如何使用这个特性来获取物品的信息。

清单 19-10 。在事件处理程序中使用 ui 对象

<!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"/>
    <script type="text/javascript">
        $(document).ready(function() {

            var flowers = ["Aster", "Daffodil", "Rose", "Peony", "Primula", "Snowdrop",
                            "Poppy", "Primrose", "Petuna", "Pansy"];

            $("#acInput").autocomplete({
                source: flowers,
                focus: displayItem,
                select: displayItem,
                change: displayItem
            })

            function displayItem(event, ui) {
                $("#itemLabel").text(ui.item.label)
            }
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
            Item Label: <span id="itemLabel"></span>
        </div>
    </form>
</body>
</html>

我添加了一个span元素,用来显示所选对象的label属性。jQuery UI 创建具有labelvalue属性的对象,即使您为source设置使用简单的字符串数组,因此您总是需要从ui.item对象中读取这些属性中的一个。在这个例子中,我使用相同的函数来显示来自focusselectchange事件的项目。你可以在图 19-8 中看到效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-8 。获取所选项目的详细信息

修改搜索结果

在结果显示给用户之前,response事件提供了修改结果的机会。在清单 19-11 的中,您可以看到我是如何处理response事件来防止Peony值被显示出来的。

清单 19-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"/>
    <script type="text/javascript">
        $(document).ready(function () {

            var flowers = ["Aster", "Daffodil", "Rose", "Peony", "Primula", "Snowdrop",
                            "Poppy", "Primrose", "Petuna", "Pansy"];

            $("#acInput").autocomplete({
                source: flowers,
                response: filterResults
            });

            function filterResults(event, ui) {
                for (var i = 0; i < ui.content.length; i++) {
                    if (ui.content[i].label == "Peony") {
                        ui.content.splice(i, 1);
                    }
                }
            }
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
        </div>
    </form>
</body>
</html>

我定义了一个名为filterResults的函数来处理response事件。在这个函数中,我列举了将呈现给用户的结果,这些结果作为一个数组通过ui.content属性访问。response事件的处理函数必须直接修改数组,所以我使用splice方法从ui.content数组中移除Peony条目。

覆盖默认选择动作

select事件有一个默认动作,就是用从弹出菜单中选择的项目的value属性的内容替换input元素的内容。这正是大多数情况下所需要的,但是这个事件可以用来补充默认操作或阻止它,并做一些完全不同的事情。清单 19-12 包含了一个通过设置相关字段的值来补充默认值的例子。

清单 19-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"/>
    <script type="text/javascript">
        $(document).ready(function() {

            var flowers = ["Aster", "Daffodil", "Rose"];

            var skus = { Aster: 100, Daffodil: 101, Rose: 102};

            $("#acInput").autocomplete({
                source: flowers,
                select: function(event, ui) {
                    $("#sku").val(skus[ui.item.value]);
                }
            })
        });
    </script>
</head>
<body>
    <form>
        <div class="ui-widget">
            <label for="acInput">Flower Name: </label><input id="acInput"/>
            <label for="sku">Stock Keeping Unit: </label><input id="sku"/>
        </div>
    </form>
</body>
</html>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示我在第九章的中描述了事件的默认动作。

当触发select事件时,我的处理函数使用ui参数获取所选项的值,并设置相关字段的值——在本例中是库存单位,它是从skus对象中获得的。这样,我可以根据初始选择为其他字段提供默认值,从而帮助用户。这在很多情况下都很有用,尤其是在选择送货地址等项目时。你可以在图 19-9 中看到结果,尽管这是一个你应该加载浏览器以获得完整效果的例子。本文档和本书中所有其他示例的 HTML 可以在 Apress 网站的源代码/下载区域免费获得(www.apress.com)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-9 。使用 select 事件填充另一个字段

使用 jQuery UI 手风琴

accordion 小部件接受一组内容元素并将其呈现出来,这样用户最多只能看到一个内容元素。当用户选择另一个时,可见内容被隐藏,产生一种让人想起同名乐器中风箱的效果。

当你不想一次显示所有内容而让用户不知所措时,手风琴非常适合呈现可以分成离散部分的内容。理想情况下,各个内容部分共享一些可以使用简单标题表达的总体主题。

制作手风琴

jQuery UI accordion 小部件是使用accordion方法应用的,如清单 19-13 所示。

清单 19-13 。制作手风琴

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <script src="jquery-2.0.2.js" type="text/javascript"></script>
    <script src="handlebars.js"></script>
    <script src="handlebars-jquery.js"></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 type="text/css">
        #accordion {margin: 5px}
        .dcell img {height: 60px}
    </style>
    <script id="flowerTmpl" type="text/x-jquery-tmpl">
        {{#flowers}}
        <div class="dcell">
            <img src="{{product}}.png"/>
            <label for="{{product}}">{{name}}:</label>
            <input name="{{product}}" value="0" />
        </div>
        {{/flowers}}
    </script>
    <script type="text/javascript">
        $(document).ready(function () {
            var data = {
                flowers: [{ "name": "Aster", "product": "aster" },
                { "name": "Daffodil", "product": "daffodil" },
                { "name": "Rose", "product": "rose" },
                { "name": "Peony", "product": "peony" },
                { "name": "Primula", "product": "primula" },
                { "name": "Snowdrop", "product": "snowdrop" },
                { "name": "Carnation", "product": "carnation" },
                { "name": "Lily", "product": "lily" },
                { "name": "Orchid", "product": "orchid" }]
            };

            var elems = $("#flowerTmpl").template(data).filter("*");
            elems.slice(0, 3).appendTo("#row1");
            elems.slice(3, 6).appendTo("#row2");
            elems.slice(6).appendTo("#row3");

            $("#accordion").accordion();

            $("button").button();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="accordion">
            <h2><a href="#">Row 1</a></h2>
            <div id="row1"></div>
            <h2><a href="#">Row 2</a></h2>
            <div id="row2"></div>
            <h2><a href="#">Row 3</a></h2>
            <div id="row3"></div>
        </div>
        <div id="buttonDiv"><button type="submit">Place Order</button></div>
    </form>
</body>
</html>

这个例子中最重要的部分是元素div的内容,它的idaccordion

...
<div id="accordion">
    <h2><a href="#">Row 1</a></h2>
    <div id="row1"></div>

    <h2><a href="#">Row 2</a></h2>
    <div id="row2"></div>

    <h2><a href="#">Row 3</a></h2>
    <div id="row3"></div>
</div>
...

我已经改变了格式,使结构更加明显。顶层的div元素是用accordion方法定位的元素。jQuery UI 在div的内容中寻找头元素(从h1h6元素),并分解内容,使得每个头都与它后面的元素相关联。在本例中,我使用了h2元素作为标题,每个标题后面都有一个div元素。我使用数据模板用花店提供的产品细节填充这些div元素。

注意,我在每个h2元素中添加了一个a元素。这是指定每个内容部分标题的方法。你可以在图 19-10 中看到 jQuery UI 是如何转换顶层div元素及其内容的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-10 。jQuery UI 折叠

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示href属性设置为#是定义仅用于 JavaScript 的a元素时的常用技术。我使用这种方法是因为它使示例更简单,但是我通常推荐使用 jQuery 动态插入a元素,这样它们就不会干扰非 JavaScript 用户。

当创建 accordion 时,第一个内容部分被显示,而其他部分被隐藏。a元素的内容被用作每个部分的标签,点击一个标签关闭当前部分并打开所选部分(在过渡期间有一个很好的动画效果,我无法使用截图显示)。你可以在图 19-11 中看到点击标题的效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-11 。手风琴过渡

配置折叠面板

accordion 支持许多配置 设置,可用于微调其行为。表 19-7 描述了这些设置,我将在接下来的章节中向你展示如何使用这些设置来配置小工具。

表 19-7 。手风琴设置

环境描述
active获取或设置要显示的内容元素。默认情况下,最初显示第一个内容元素。
animate指定从一个内容元素过渡到另一个内容元素时将使用的动画。有关 jQuery UI 动画的详细信息,请参见第三十五章。
collapsibletrue时,可以折叠所有的内容部分。默认为false
disabledtrue时,手风琴被禁用。默认为false
event指定 header 元素中触发转换到另一个 content 元素的事件。默认为click
header指定哪些元素将用作标题。
heightStyle控制手风琴及其面板的高度。
icons指定折叠面板中使用的图标。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在 jQuery UI 1.10 中,animate设置取代了animated设置;heightStyle选项替代autoHeightclearStylefillSpace设置;并且当使用icons属性时,使用新的属性名称来指定用于所选内容面板(activeHeader)的图标。

设置手风琴的高度

属性控制手风琴及其面板的高度。有三个支持的值,我在表 19-8 中描述过。

表 19-8 。heightStyle 的值

名字描述
auto所有面板将被设置为最高面板的高度
fill扩展折叠面板以填充父元素的高度
content每个面板都与其内容一样高

您可以根据内容元素的高度或父元素的高度来设置折叠面板的高度。最常见的技术是依赖于默认的auto值,它将所有的内容元素设置为相同的高度(最高的内容元素的高度),并根据该高度调整折叠的大小。

这是我在前面的例子中使用的方法,尽管在使用包含图像的内容元素时需要小心,特别是当使用 jQuery 将img元素插入到文档中时。问题是,在加载所有图像之前,可以调用accordion方法,这导致 jQuery UI 从浏览器获得关于内容元素高度的误导信息。在我的示例文档中,内容div元素的高度在图像加载前是 55 像素,加载后是 79 像素。当 accordion 显示出意外的滚动条来显示内容时,你就可以判断你是否碰到了这个问题,如图图 19-12 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-12 。不正确的高度信息导致的问题

当加载图像时,jQuery UI 不会检测到内容元素高度的变化,最终会错误地显示内容。为了解决这个问题,您需要提供关于内容元素在加载所有外部资源后的高度的信息。有很多方法可以做到这一点,在本例中,我选择为style元素中的img元素设置 CSS height属性,如下所示:

...
<style type="text/css">
    #accordion {margin: 5px}
    .dcell img {height: 60px}
</style>
...

撇开图像问题不谈,当您希望每个内容元素的高度一致时,auto值是有用的,但是当内容元素的大小之间存在很大差异时,它会导致一些不吸引人的视觉效果。清单 19-14 显示了一个script元素,它以不同的方式插入产品信息元素。

清单 19-14 。高度差很大的手风琴

...
<script type="text/javascript">
    $(document).ready(function () {

        var data = {
            flowers: [{ "name": "Aster", "product": "aster" },
            { "name": "Daffodil", "product": "daffodil" },
            { "name": "Rose", "product": "rose" },
            { "name": "Peony", "product": "peony" },
            { "name": "Primula", "product": "primula" },
            { "name": "Snowdrop", "product": "snowdrop" },
            { "name": "Carnation", "product": "carnation" },
            { "name": "Lily", "product": "lily" },
            { "name": "Orchid", "product": "orchid" }]
        };

        var elems = $("#flowerTmpl").template(data).filter("*");
        elems.slice(0, 3).appendTo("#row1");
        elems.slice(3, 6).appendTo("#row2");
        elems.slice(6).appendTo("#row3");

        $("<h2><a href=#>All</a></h2><div id=row0></div>").prependTo("#accordion")
            .filter("div").append($("#row1, #row2, #row3").clone());

        $("#accordion").accordion();

        $("button").button();
    });
</script>
...

为了创建一个超高的内容元素,我使用 jQuery 克隆了现有的 content div元素,并将它们插入到一个新的内容元素中,创建了一个显示所有产品的面板。这个新面板的高度是其他面板的三倍,这导致当显示较小的内容元素时,accordion 会显示大量的空白空间,如图 19-13 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-13 。高度差较大时自动设置的效果

如果一大片空白空间不适合您的应用,那么您可以简单地将heightStyle属性更改为content,如清单 19-15 所示。

清单 19-15 。更改高度样式设置

...
$("#accordion").accordion({
    heightStyle: "content"
});
...

作为内容元素之间过渡的一部分,手风琴现在将改变其高度,如图图 19-14 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-14 。手风琴自己调整大小,以适应不同的内容高度

这是一种更简洁的显示内容的方法,但是这意味着页面的布局会随着 accordion 自身的调整而改变。如果控制键不断在屏幕上移动,这可能会让用户感到厌烦。

使用父对象确定手风琴的高度

一种完全不同的方法是设置 accordion 的大小,以便它简单地填充其父元素。当我处理动态生成的内容时,我发现这非常有用,因为我不能很好地控制大小,也不想调整布局。你可以通过fill设置来调整手风琴的大小,如清单 19-16 中的所示。

清单 19-16 。调整折叠面板的大小以填充父元素

...
<script type="text/javascript">
    $(document).ready(function () {

        var data = {
            flowers: [{ "name": "Aster", "product": "aster" },
            { "name": "Daffodil", "product": "daffodil" },
            { "name": "Rose", "product": "rose" },
            { "name": "Peony", "product": "peony" },
            { "name": "Primula", "product": "primula" },
            { "name": "Snowdrop", "product": "snowdrop" },
            { "name": "Carnation", "product": "carnation" },
            { "name": "Lily", "product": "lily" },
            { "name": "Orchid", "product": "orchid" }]
        };

        var elems = $("#flowerTmpl").template(data).filter("*");
        elems.slice(0, 3).appendTo("#row1");
        elems.slice(3, 6).appendTo("#row2");
        elems.slice(6).appendTo("#row3");

        $("<h2><a href=#>All</a></h2><div id=row0></div>").prependTo("#accordion")
            .filter("div").append($("#row1, #row2, #row3").clone());

        $("#accordion").wrap("<div style='height:300px'></div>");

        $("#accordion").accordion({
            heightStyle: "fill"
        });

        $("button").button();
    });
</script>
...

在这个例子中,我将accordion元素包装在一个新的父div元素中,该元素具有 300 像素的固定大小。当我调用手风琴方法时,我将heightStyle设置为fill。如果父元素比内容元素小,那么 accordion 会添加一个滚动条。如果父元素大于内容元素,则添加填充。在图 19-15 中可以看到滚动条的应用。这是因为显示所有花朵的内容元素比父元素的 300 像素高。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-15 。使用手风琴填充父对象的高度

更改事件类型

默认情况下,用户通过单击来打开和关闭内容元素。您可以通过event设置来改变这种行为,如清单 19-17 中的所示。

清单 19-17 。使用事件设置

...
<script type="text/javascript">
    $(document).ready(function () {

        var data = {
            flowers: [{ "name": "Aster", "product": "aster" },
            { "name": "Daffodil", "product": "daffodil" },
            { "name": "Rose", "product": "rose" },
            { "name": "Peony", "product": "peony" },
            { "name": "Primula", "product": "primula" },
            { "name": "Snowdrop", "product": "snowdrop" },
            { "name": "Carnation", "product": "carnation" },
            { "name": "Lily", "product": "lily" },
            { "name": "Orchid", "product": "orchid" }]
        };

        var elems = $("#flowerTmpl").template(data).filter("*");
        elems.slice(0, 3).appendTo("#row1");
        elems.slice(3, 6).appendTo("#row2");
        elems.slice(6).appendTo("#row3");

        $("#accordion").accordion({
            event: "mouseover"
        });

        $("button").button();
    });
</script>
...

在清单 19-17 中,我使用了event设置来指定内容元素应该被打开以响应mouseover事件(我在第九章中描述过)。这一变化的效果是,一旦鼠标指针进入内容元素的标签,jQuery UI 就会打开该元素并显示其内容。我不能在截图中显示这种效果,但是我建议您加载这个示例,看看它是如何工作的。这是一个简洁的特性,但是我建议您小心使用它。用户通常很快就能理解点击图标打开一部分内容的想法,但是对鼠标事件的响应会带来令人不安和惊讶的用户体验。

选择活动标题

accordion 的默认行为最初是向用户显示第一个内容元素。您可以使用active属性来改变这种行为。您将active设置为想要显示的内容元素的索引,如清单 19-18 所示。

清单 19-18 。使用活动属性

...
<script type="text/javascript">
    $(document).ready(function () {

        var data = {
            flowers: [{ "name": "Aster", "product": "aster" },
            { "name": "Daffodil", "product": "daffodil" },
            { "name": "Rose", "product": "rose" },
            { "name": "Peony", "product": "peony" },
            { "name": "Primula", "product": "primula" },
            { "name": "Snowdrop", "product": "snowdrop" },
            { "name": "Carnation", "product": "carnation" },
            { "name": "Lily", "product": "lily" },
            { "name": "Orchid", "product": "orchid" }]
        };

        var elems = $("#flowerTmpl").template(data).filter("*");
        elems.slice(0, 3).appendTo("#row1");
        elems.slice(3, 6).appendTo("#row2");
        elems.slice(6).appendTo("#row3");

        $("#accordion").accordion({
            active: 1
        });

        $("button").button();
    });
</script>
...

效果是 accordion 最初在索引 1 处打开行(索引是从零开始的,所以这是第二个内容元素),如图 19-16 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-16 。选择要显示的初始内容元素

通过将active设置为false,您也可以不激活任何内容。如果这样做,您还必须将可折叠设置设为true。这将禁用一个内容元素必须始终可见的默认策略。清单 19-19 显示了这些设置的应用。

清单 19-19 。禁用最初活动的内容元素

...
$("#accordion").accordion({
    active: false,
    collapsible: true
});
...

你可以在图 19-17 中看到这些设置的效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-17 。没有初始活动内容元素的手风琴

accordion 的工作方式和以前一样,只是没有最初活动的内容元素,并且所有的内容元素都可以关闭。当屏幕空间有限并且用户对 accordion 中的内容不感兴趣时,这是一种有用的技术。

更改折叠图标

您可以使用icons设置来更改折叠内容标题中使用的图标。清单 19-20 提供了一个例子。

清单 19-20 。更改手风琴使用的图标

...
$("#accordion").accordion({
    collapsible: true,
    icons: {
        header: "ui-icon-zoomin",
        activeHeader: "ui-icon-zoomout"
    }
});
...

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在 jQuery UI 1.10 中,activeHeader属性取代了headerSelected属性。

您将icons设置为一个具有headeractiveHeader属性的对象。第一个属性指定内容元素关闭时使用的图标,第二个属性指定内容元素打开时使用的图标。我倾向于将这个特性与collapsible设置结合使用,因为当使用图标暗示用户可以执行某个动作时,它会给人一种更自然的感觉。你可以在图 19-18 中看到这些图标是如何出现的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 19-18 。为折叠部分标题使用自定义图标

使用手风琴的方法

jQuery UI accordion 定义了许多方法,如表 19-9 中所述。

表 19-9 。手风琴方法

方法描述
accordion("destroy")input元素中删除折叠功能
accordion("disable")禁用手风琴
accordion("enable")启用手风琴
accordion("option")设置一个或多个选项
accordion("refresh")刷新小工具面板的大小。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示jQuery UI 1.10 中移除了activate方法。请使用我在上一节中描述的active选项。resize方法已被refresh方法取代。

refresh方法更新折叠面板的大小,以反映内容元素的变化。大小变化的影响取决于我在前面部分描述的heightStyle选项的值。其他方法是 jQuery UI 为所有元素提供的方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示从 jQuery UI 1.10 开始,调用refresh方法也将更新面板集以反映内容元素的变化,允许添加或删除元素。

使用手风琴事件

jQuery UI accordion 小部件支持表 19-10 中所示的三个事件。

表 19-10 。手风琴比赛

事件描述
activate当内容面板被激活时触发
beforeActivate在内容面板被激活之前触发
create创建手风琴时触发

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在 jQuery UI 1.10 中,accordion 小部件定义的事件发生了变化。changestart事件被替换为beforeActivate,change事件被替换为activate。传递给这些事件的处理函数的额外的ui对象使用与旧事件不同的属性名,如表 19-11 所述。

表 19-11 。change 和 changestart 事件的 ui 对象的属性

名字描述
newHeader新活动内容元素的标题元素
oldHeader先前活动内容元素的标题元素
newPanel新活动的内容元素
oldPanel先前活动的内容元素

您可以使用beforeActivateactive事件来监控内容元素之间的转换,如清单 19-21 所示。

清单 19-21 。使用变更事件

...
<script type="text/javascript">
    $(document).ready(function () {

        var data = {
            flowers: [{ "name": "Aster", "product": "aster" },
            { "name": "Daffodil", "product": "daffodil" },
            { "name": "Rose", "product": "rose" },
            { "name": "Peony", "product": "peony" },
            { "name": "Primula", "product": "primula" },
            { "name": "Snowdrop", "product": "snowdrop" },
            { "name": "Carnation", "product": "carnation" },
            { "name": "Lily", "product": "lily" },
            { "name": "Orchid", "product": "orchid" }]
        };

        var elems = $("#flowerTmpl").template(data).filter("*");
        elems.slice(0, 3).appendTo("#row1");
        elems.slice(3, 6).appendTo("#row2");
        elems.slice(6).appendTo("#row3");

        $("#accordion").accordion({
            active: false,
            collapsible: true,
            activate: handleAccordionChange
        })

        function handleAccordionChange(event, ui) {
            if (ui.oldHeader.length) {
                console.log("Old header: " + ui.oldHeader[0].innerText);
            }
            if (ui.newHeader.length) {
                console.log("New header: " + ui.newHeader[0].innerText);
            }
        }

        $("button").button();
    });
</script>
...

我使用activate事件来响应被更改的内容元素。jQuery UI 通过处理函数的附加参数将活动元素的信息传递给事件处理函数,就像 autocomplete 小部件一样。这个附加参数通常被命名为ui,定义了表 19-11 中所示的属性。

这些属性是数组,这就是为什么我在第一个索引处获取HTMLElement对象并将innerText属性的值写入控制台之前测试了length属性。

摘要

在本章中,我向您展示了 jQuery UI 自动完成和 accordion 小部件。这些都遵循了我在第十八章中使用的基本模式,但是提供了更丰富的功能和更广泛的配置选项来定制小部件,以便它们可以很好地适应您的 web 应用模型。在第二十章中,我向你展示了标签小工具。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16727.html
标签
VKDoc
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!