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

jQuery2 高级教程(八)

2024-08-21 22:08:06 前端知识 前端哥 733 456 我要收藏

原文:Pro jQuery 2.0

协议:CC BY-NC-SA 4.0

二十、使用选项卡小部件

tabs 小部件表面上类似于我在第十九章中描述的 accordion,但是提供了更多的功能和定制的机会。与前面的小部件章节一样,我从如何创建小部件的细节开始,然后向您展示小部件支持的设置、方法和事件。我用一个例子来结束这一章,这个例子展示了如何使用 tabs 小部件将表单分部分呈现给用户,这是一种处理需要大量数据输入的长表单的有用技术。表 20-1 对本章进行了总结。

表 20-1 。章节总结

问题解决办法列表
创建选项卡小部件定义一个标签和内容元素结构,并调用tabs方法one
通过 Ajax 获取标签的内容将选项卡a元素的href属性设置为应该在内容面板中显示的 HTML 文档2, 3
获取或设置活动选项卡使用active设置four
禁用单个选项卡使用disabled设置five
更改激活选项卡的事件使用event设置six
允许停用所有选项卡使用collapsible设置seven
添加或删除选项卡更改底层 HTML 元素,然后调用refresh方法eight
强制加载远程内容使用load方法nine
在发出 Ajax 请求之前对其进行配置,并在加载时修改远程内容处理beforeLoadload事件10, 11
跨多个选项卡显示表单使用div元素分割表单,添加一个标签结构,并调用tabs方法12–14
验证显示在多个选项卡中的表单内容处理beforeActivateactivate事件Fifteen

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

在 jQuery UI 1.10 中,tabs 小部件经历了一次重大的 API 变化。方法和配置选项更少,为了与其他小部件的更改保持一致,在进行更改时,更依赖于直接操作小部件所应用的元素。

删除了以下选项:fxajaxOptionscachespinnerselectedidPrefixtabTemplatepanelTemplatecookie。删除了以下方法:urlabortselectaddremovelength。tabs 小部件定义的事件集已经被简化。有关新事件的详细信息,请参见“使用选项卡事件”一节。

这些变化可能看起来很剧烈,但结果是一个更简单、更容易使用的小部件。通过使用 jQuery 操作底层 HTML 元素,然后使用新的refresh方法更新小部件的状态,方法和选项提供的所有功能仍然可用,如本章中的清单所示。

创建选项卡

使用tabs方法创建 jQuery UI 选项卡。和 accordion 小部件一样,tab 小部件需要特定的 HTML 元素结构才能工作,如清单 20-1 所示。

清单 20-1 。创建 jQuery UI 选项卡

<!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"/>
    <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("#tab1");
            elems.slice(3, 6).appendTo("#tab2");
            elems.slice(6).appendTo("#tab3");

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

应用tabs方法的元素必须包含两种元素。第一个是内容元素,这些元素的内容应该出现在标签中。第二种元素是结构元素,它为 jQuery UI 选项卡小部件提供创建选项卡结构所需的信息。

我使用div元素来提供结构。在下面的例子中,我使用了三个div元素,每个元素保存一行花卉产品信息,就像前面的例子一样:

...
<div id="tab1"></div>
<div id="tab2"></div>
<div id="tab3"></div>
...

重要的是每个内容元素都有一个id属性,以便 jQuery UI 选项卡小部件可以找到要显示的正确元素。对于结构,我使用了li元素,每个元素包含一个a元素,如下:

...
<ul>
    <li><a href="#tab1">Row 1</a>
    <li><a href="#tab2">Row 2</a>
    <li><a href="#tab3">Row 3</a>
</ul>
...

li项的数量定义了标签的数量。a元素的内容被用作选项卡标签,href属性指定该选项卡与哪个内容元素相关。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示我使用数据模板来动态生成选项卡内容,因为它让我更清楚地显示所需的结构。内容可以静态定义,或者像我在下一节中解释的那样,从服务器动态获取。

你可以在图 20-1 中看到例子中的结构是如何转换成一组选项卡的。

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

图 20-1 。创建 jQuery UI 选项卡

标签是一个熟悉的用户界面隐喻。单击一个选项卡会导致 jQuery UI 显示相应的内容元素。与 accordion 一样,tabs 小部件可以让您以相对简洁的方式呈现大量内容,让用户能够专注于对他来说重要的内容。这意味着你必须仔细考虑标签和它们的内容是如何相互关联的。目标应该是将你的内容分组,以减少用户在标签之间切换来找到她想要的内容的次数,同时保留内容元素的自然分组。与任何用户界面一样,这需要对用户正在执行的任务以及她的工作流(而不是你的系统)如何运行有一个坚实的理解。

用 Ajax 获取标签内容

选项卡小部件的一个很好的特性是能够通过 Ajax 获取选项卡内容。为此,您只需指定一个 URL 作为适当的a元素的href属性。通过 Ajax 获取内容的标签被称为远程标签。为了演示这个特性,我创建了一个名为tabflowers.html的 HTML 文档,其内容如清单 20-2 所示。

清单 20-2 。tabflowers.html 文件的内容

<div>
    <div class="dcell">
        <img src="aster.png"/><label for="aster">Aster:</label>
        <input name="aster" value="0" />
    </div>
    <div class="dcell">
        <img src="daffodil.png"/><label for="daffodil">Daffodil:</label>
        <input name="daffodil" value="0" />
    </div>
    <div class="dcell">
        <img src="rose.png"/><label for="rose">Rose:</label>
        <input name="rose" value="0" />
    </div>
</div>
<div>
    <div class="dcell">
        <img src="peony.png"/><label for="peony">Peony:</label>
        <input name="peony" value="0" />
    </div>
    <div class="dcell">
        <img src="primula.png"/><label for="primula">Primula:</label>
        <input name="primula" value="0" />
    </div>
    <div class="dcell">
        <img src="snowdrop.png"/><label for="snowdrop">Snowdrop:</label>
        <input name="snowdrop" value="0" />
    </div>
</div>

为了保持示例简单,我使用了与生成的内容元素相同的结构和内容。清单 20-3 展示了如何使用tabflowers.html文件作为标签的内容。

清单 20-3 。通过 Ajax 获取标签的内容

...
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="tabs">
            <ul>
                <li><a href="tabflowers.html">Ajax Content</a>
                <li><a href="#tab1">Row 1</a>
                <li><a href="#tab2">Row 2</a>
                <li><a href="#tab3">Row 3</a>
            </ul>
            <div id="tab1"></div>
            <div id="tab2"></div>
            <div id="tab3"></div>
        </div>
        <div id="buttonDiv"><button type="submit">Place Order</button></div>
    </form>
</body>
...

在清单 20-2 中,我添加了一个名为 Ajax Content 的新标签,并指定了应该加载的内容的 URL。你可以在图 20-2 中看到效果。

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

图 20-2 。通过 Ajax 获取标签的内容

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示你不需要为远程标签页创建内容元素。这是由选项卡小部件自动完成的。

配置标签窗口小部件

乍一看,tabs 小部件可能看起来像是我在第十九章中向您展示的 accordion 小部件的垂直变体。有一些共同的特征,但是当您使用选项卡时,有一组更广泛的配置选项和设置。表 20-2 描述了 jQuery UI tabs 小部件支持的设置。在接下来的小节中,我将向您展示如何使用这些设置来配置小部件。

表 20-2 。选项卡设置

环境描述
active获取或设置当前显示的选项卡;使用基于零的索引来指定单个面板,并且所有面板都可以通过指定false来关闭(但是这仅在collapsible被设置为true时有效)
collapsible当设置为true时,所有选项卡都关闭
disabled用于启用/禁用单个选项卡
event用于设置触发选项卡间转换的事件
heightStyle指定如何确定小工具及其选项卡的高度
hide指定标签页关闭时的动画——我在第三十五章中描述了 jQuery UI 动画。
show指定标签页打开时的动画——我在第三十五章中描述了 jQuery UI 动画。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示在 jQuery UI 1.10 版本中,选项卡小部件的配置选项发生了很大的变化。完整的细节请参见本章开头的注释,但是新的选项集——如表 20-2 所示——更加简单,并且与其他 jQuery UI 小部件更加一致。

选择活动选项卡

active设置支持确定和改变当前显示的标签,如清单 20-4 所示。

清单 20-4 。使用活动选项获取和设置显示的选项卡

<!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>
        #radioDiv { text-align: center; margin-top: 10px;}
    </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("#tab1");
            elems.slice(3, 6).appendTo("#tab2");
            elems.slice(6).appendTo("#tab3");

            $("#tabs").tabs();

            $("#radioDiv").buttonset().change(function (e) {
                $("#tabs").tabs("option", "active", e.target.value);
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="tabs">
            <ul>
                <li><a href="tabflowers.html">Ajax Content</a>
                <li><a href="#tab1">Row 1</a>
                <li><a href="#tab2">Row 2</a>
                <li><a href="#tab3">Row 3</a>
            </ul>
            <div id="tab1"></div>
            <div id="tab2"></div>
            <div id="tab3"></div>
        </div>
        <div id="radioDiv">
            <input type="radio" name="tabNo" id="one" value="1" />
                <label for="one">1</label>
            <input type="radio" name="tabNo" id="two" value="2"/>
                <label for="two">2</label>
            <input type="radio" name="tabNo" id="three" value="3"/>
                <label for="three">3</label>
        </div>
    </form>
</body>
</html>

我在文档中添加了一个 jQuery UI 按钮集,如第十八章中的所述。我使用 jQuery change方法来注册一个处理函数,当单击按钮集中的一个按钮时,这个函数被调用。handler 函数使用option方法设置active属性,产生如图 20-3 中所示的效果。

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

图 20-3 。使用活动设置更改活动选项卡

禁用单个选项卡

如果您使用boolean值,则disabled设置会改变选项卡小部件的状态,但是也可以通过使用一组数字来启用和禁用单个选项卡。清单 20-5 演示了。

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

            $("#tabs").tabs();

            $("input:checkbox").button().click(function () {
                var disabledPositions = [];
                $("input:checked").each(function (index, elem) {
                    disabledPositions.push(Number(elem.value));
                })

                $("#tabs").tabs("option", "disabled", disabledPositions)
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="tabs">
            <ul>
                <li><a href="#tab1">Tab 1</a>
                <li><a href="#tab2">Tab 2</a>
                <li><a href="#tab3">Tab 3</a>
            </ul>
            <div id="tab1">This is the content for tab 1</div>
            <div id="tab2">This is the content for tab 2</div>
            <div id="tab3">This is the content for tab 3</div>
        </div>
        <div id="buttonDiv">
            <label for="cb0">Tab 1</label><input type="checkbox" id="cb0" value=0>
            <label for="cb1">Tab 2</label><input type="checkbox" id="cb1" value="1">
            <label for="cb2">Tab 3</label><input type="checkbox" id="cb2" value="2">
        </div>
    </form>
</body>
</html>

我创建了一个包含静态内容的 tabs 小部件,并添加了一组复选框,我将它们转换成了 jQuery UI 切换按钮。当点击其中一个按钮时,对应的选项卡被启用或禁用,如图图 20-4 所示。

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

图 20-4 。禁用和启用选项卡以响应按钮点击

更改事件触发器

默认情况下,tabs 小部件响应click事件,这意味着用户必须单击一个选项卡来激活它。您可以使用event设置来指定要响应的不同事件。这对于响应鼠标事件非常有用,如清单 20-6 所示。

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

            $("#tabs").tabs({
                event: "mouseover"
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="tabs">
            <ul>
                <li><a href="#tab1">Tab 1</a>
                <li><a href="#tab2">Tab 2</a>
                <li><a href="#tab3">Tab 3</a>
            </ul>
            <div id="tab1">This is the content for tab 1</div>
            <div id="tab2">This is the content for tab 2</div>
            <div id="tab3">This is the content for tab 3</div>
        </div>
    </form>
</body>
</html>

我在清单中指定了mouseover事件,这意味着当鼠标在选项卡标签上移动时,选项卡小部件将在选项卡之间切换。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示我建议谨慎使用这种方法,就像我对 accordion 小部件的相同设置所做的那样。这在视觉上很吸引人,但是会产生一种令人讨厌的效果,迫使用户注意不要将鼠标从他想要交互的标签上移开。

使用可折叠标签

你可以通过使用collapsible设置来创建一种标签和折叠的混合体,如清单 20-7 所示。

清单 20-7 。使用可折叠设置

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#tabs").tabs({
            collapsible: true
        });
    });
</script>
...

collapsible设置为true时,单击活动选项卡就像折叠内容元素一样折叠它。你可以在图 20-5 中看到这个过渡。

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

图 20-5 。折叠活动选项卡

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示为了完整起见,我已经包括了这个设置,但是我从来没有在我自己的项目中使用过它,因为它的结果会让用户感到困惑。

使用选项卡方法

表 20-3 显示了 jQuery UI tabs 小部件支持的方法。

表 20-3 。选项卡方法

方法描述
tabs("destroy")从基础 HTML 元素中移除选项卡小部件
tabs("disable")禁用整个小部件或单个选项卡(有关使用相应设置的示例,请参见“使用可折叠选项卡”一节)
tabs("enable")启用整个小部件或单个选项卡
tabs("option")更改一个或多个设置(有关配置 jQuery UI 小部件的详细信息,请参见第十八章中的“配置按钮”一节)
tabs("load")使用 Ajax 请求显式加载选项卡的内容
tabs("refresh")更新小部件以反映底层 HTML 元素的变化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示tabs 小部件支持的方法集在 1.10 版本中发生了变化。删除了以下方法:addremoveselecturllengthabortaddremove方法已经被一个叫做refresh的新方法所取代;通过active设置可以使用select方法的功能;您可以使用新的beforeActivate事件实现功能性abort方法。length方法没有替代功能。

添加和删除选项卡

我使用 jQuery UI tabs 小部件来定义用于操作显示给用户的选项卡集的addremove方法。这些方法在 jQuery UI 1.10 中被删除了,取而代之的是refresh方法,它根据小部件所应用到的底层 HTML 元素的变化来更新选项卡。在清单 20-8 中,你可以看到如何使用刷新方法。

清单 20-8 。使用 refresh 方法更新选项卡小部件

<!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 type="text/css">
        #buttons {margin: 5px 0}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {

            $("#tabs").tabs();

            $("button").button().click(function (e) {
                var tabsElem = $("#tabs");
                if (this.id == "add") {
                    var tabID = tabsElem.children("div").length + 1;
                    tabsElem.children("ul").append($("<li>").append($("<a>")
                        .attr("href", "#tab" + tabID).text("Tab " + tabID)));
                    $("<div>").attr("id", "tab" + tabID)
                        .text("This is the content for tab " + tabID).appendTo(tabsElem);
                } else {
                    tabsElem.find("li").first().remove();
                    tabsElem.children("div").first().remove();
                }
                tabsElem.tabs("refresh");
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="buttons" class="ui-widget">
        <button id="add">Add Tab</button>
        <button id="remove">Remove Tab</button>
    </div>
    <div id="tabs">
        <ul>
            <li><a href="#tab1">Tab 1</a>
            <li><a href="#tab2">Tab 2</a>
            <li><a href="#tab3">Tab 3</a>
        </ul>
        <div id="tab1">This is the content for tab 1</div>
        <div id="tab2">This is the content for tab 2</div>
        <div id="tab3">This is the content for tab 3</div>
    </div>
</body>
</html>

我添加了一对button元素,用于添加和删除选项卡小部件使用的lidiv元素。当点击Add Tab按钮时,我会生成新元素,并将它们添加到文档对象模型(DOM)中。当点击Remove Tab按钮时,我移除我能找到的第一个lidiv元素。

在做了这些更改后,我调用了refresh方法,通知 tabs 小部件它应该自我更新以反映我所做的更改,创建了如图 20-6 所示的效果。

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

图 20-6 。添加和删除选项卡

触发选项卡 Ajax 请求

默认情况下,当用户打开包含远程内容的选项卡时,tabs 小部件只会对该选项卡发出 Ajax 请求。这种方法可以防止请求可能永远不会显示的内容,但是会导致用户打开标签时的延迟。您可以告诉 tabs 小部件使用load方法显式加载远程标签的内容,如清单 20-9 所示。

清单 20-9 。使用 load 方法显式获取远程内容

<!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 type="text/css">
        #buttons {margin: 5px 0}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {

            $("#tabs").tabs();

            $("#load").button().click(function (e) {
                var tabsElem = $("#tabs");

                tabsElem.find("a").each(function (index, elem) {
                    if (elem.href.indexOf("example.html") == -1) {
                        tabsElem.tabs("load", index);
                    }
                });
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>

    <div id="buttons" class="ui-widget">
        <button id="load">Load</button>
    </div>

    <div id="tabs">
        <ul>
            <li><a href="#tab1">Tab 1</a>
            <li><a href="#tab2">Tab 2</a>
            <li><a href="#tab3">Tab 3</a>
            <li><a href="tabflowers.html">Ajax Content</a>
        </ul>
        <div id="tab1">This is the content for tab 1</div>
        <div id="tab2">This is the content for tab 2</div>
        <div id="tab3">This is the content for tab 3</div>
    </div>
</body>
</html>

load方法的参数是您想要加载内容的远程标签的索引。在这种情况下,我使用了load方法来响应被点击的按钮。

使用选项卡事件

jQuery UI tabs 小部件支持的事件集在表 20-4 中描述,我将在接下来的章节中描述它们。

表 20-4 。标签事件

事件描述
create当 tabs 小部件应用于底层 HTML 元素时触发
beforeActivate在选项卡面板显示给用户之前触发
activate向用户显示选项卡面板后触发
beforeLoad当远程选项卡的内容即将被加载时触发
load当远程选项卡的内容已加载时触发

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示jQuery UI 1.10 版本改变了 tabs 小部件支持的事件集,删除了selectshowaddremoveenabledisable事件,增加了beforeActivateactivatebeforeLoad事件。被移除的事件是没有意义的,因为 tabs 小部件现在依赖于底层 HTML 元素的状态(和refresh方法),或者因为可以使用新事件重新创建功能。

拦截 Ajax 请求

在请求远程标签的内容之前,触发beforeLoad事件。处理函数被传递一个 jQuery 事件对象和一个附加对象——通常在处理函数中被赋予名称ui——它定义了表 20-5 中所示的属性。

表 20-5 。传递给 beforeLoad 事件处理函数的附加对象的属性

名字描述
tab返回一个包含远程选项卡的选项卡元素的jQuery对象
panel返回一个包含远程选项卡面板元素的jQuery对象
jqXHR返回将用于发出 Ajax 请求的jqXHR对象
ajaxSettings返回一个地图对象,该对象将被传递给发出请求的$.ajax方法

这些属性揭示了 jQuery UI 和 jQuery 之间的紧密集成,通过构建我在第十四章和第十五章中描述的 jQuery Ajax 功能。在清单 20-10 中,您可以看到我如何处理beforeLoad事件来调整 Ajax 请求的设置。

清单 20-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"/>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#tabs").tabs({
                beforeLoad: function (e, ui) {
                    ui.ajaxSettings.url = "flowers.html";
                }
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="tabs">
        <ul>
            <li><a href="#tab1">Tab 1</a>
            <li><a href="#tab2">Tab 2</a>
            <li><a href="#tab3">Tab 3</a>
            <li><a href="tabflowers.html">Ajax Content</a>
        </ul>
        <div id="tab1">This is the content for tab 1</div>
        <div id="tab2">This is the content for tab 2</div>
        <div id="tab3">This is the content for tab 3</div>
    </div>
</body>
</html>

我为beforeLoad事件注册的处理函数设置了ui.ajaxSettings对象的url属性,以改变远程选项卡将显示的内容的来源。代替 HTML 元素指定的tabflowers.html文件,将加载flowers.html文件。

操纵远程标签数据

当一个远程标签的数据已经从服务器加载,并且可以用来在内容显示给用户之前操作内容时,触发load事件。处理函数传递了一个 jQuery 事件对象和一个额外的ui对象,该对象定义了表 20-6 中显示的属性。

表 20-6 。传递给加载事件处理函数的附加对象的属性

名字描述
tab返回一个包含已加载选项卡元素的jQuery对象
panel返回一个jQuery对象,该对象包含内容被加载到的元素

注意,ui对象返回的属性都没有直接引用从服务器加载的内容。相反,处理函数可以访问选项卡小部件用于选项卡标题和内容面板的元素。在清单 20-11 中,您可以看到我如何使用这些元素来改变标签的标题并操作从服务器加载的内容。

清单 20-11 。处理选项卡加载事件

...
<script type="text/javascript">
    $(document).ready(function () {
        $("#tabs").tabs({
            load: function (e, ui) {
                ui.tab.find("a").text("Loaded!");
                ui.panel.children().first().remove();
            }
        });
    });
</script>
...

我使用ui.tab属性来定位用于选项卡的a元素,并调用 jQuery text 方法来更改标题。我使用ui.panel属性定位从服务器加载的第一个子内容元素,并将其从 DOM 中移除。你可以在图 20-7 中看到效果。

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

图 20-7 。处理加载事件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示注意,我不必调用refresh方法,尽管我正在修改 tabs 小部件所依赖的 DOM 元素。触发加载事件后,会自动应用刷新。

使用选项卡显示表单

这是一种非常有用的技术,可以让长表单更容易理解,同时让用户感觉到她在表单中前进了多远。首先,清单 20-12 显示了包含我将使用的表单的文档。

清单 20-12 。包含表单的文档

<!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="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        #tab2 input, #tab3 input {width: 200px; text-align: left}
        #tab1, #tab2, #tab3 {padding: 10px}
        .fl {float: left}
        #buttonDiv {clear: both}
        #tabs, h1 {margin: 10px}
        .regLabel {width: auto}
    </style>
    <script id="flowerTmpl" type="text/x-jquery-tmpl">
        {{#flowers}}
            <div class="dcell ui-widget">
                <img src="{{product}}.png"/>
                <label for="{{product}}">{{name}}:</label>
                <input name="{{product}}" value="0"/>
            </div>
        {{/flowers}}
    </script>
    <script id="detailsTmpl" type="text/x-jquery-tmpl">
        {{#details}}
            <div class="ui-widget">
                <label for="{{name}}">{{name}}:</label>
                <input name="{{name}}" placeholder="{{hint}}"/>
            </div>
        {{/details}}
    </script>
    <script type="text/javascript">
        $(document).ready(function () {

            var data = [{ "name": "Aster", "product": "aster" },
                        { "name": "Daffodil", "product": "daffodil" },
                        { "name": "Rose", "product": "rose" },
                        { "name": "Peony", "product": "peony" }];

            var elems = $("#flowerTmpl").template({ flowers: data }).filter("*");
            elems.slice(0, 2).appendTo("#row1");
            elems.slice(2, 4).appendTo("#row2");

            var detailsData = [{ name: "Name", hint: "Enter your name" },
                    { name: "Street", hint: "Enter your street" },
                    { name: "City", hint: "Enter your city" },
                    { name: "State", hint: "Enter your state" },
                    { name: "Zip", hint: "Enter your zip code" }];

            $("#detailsTmpl").template({ details: detailsData }).filter("*")
                .appendTo("#tab2").clone().appendTo("#tab3")

            $("button").button();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="tabs" class="ui-widget">
            <ul>
                <li><a href="#tab1">1\. Select Products</a>
                <li><a href="#tab2">2\. Your Details</a>
                <li><a href="#tab3">3\. Your Shipping Address</a>
            </ul>
            <div id="tab1">
                <h2>1\. Select Products</h2>
                <div id="row1"></div>
                <div id="row2"></div>
            </div>
            <div id="tab2" class="fl">
                <h2>2\. Your Details</h2>
            </div>
            <div id="tab3" class="fl">
               <h2>3\. Your Shipping Address</h2>
            </div>
        </div>
        <div id="buttonDiv"><button type="submit">Place Order</button></div>
    </form>
</body>
</html>

我在文档中添加了一些额外的内容和结构,以充实早期的示例。花卉产品较少,但是我在文档中添加了一些区域来捕获用户的个人和运输细节。你可以在图 20-8 中看到基本形式。

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

图 20-8 。用于选项卡小部件的多部分表单

该表单没有什么特别之处,只是非常适合与 jQuery UI tabs 小部件一起使用,因为它被整齐地划分为不同的区域,每个区域都可以显示在一个选项卡中。

我已经使用数据模板以编程方式添加了大部分内容,您可以看到我如何使用在前面章节中演示的 jQuery 功能从数据中生成元素,根据需要克隆它们,然后将结果添加到文档中。这并不是使用选项卡显示表单的必要条件,但是在一本关于 jQuery 的书中,我喜欢尽可能多地使用核心特性。

您还可以在图中看到ul元素以及它包含的指向内容元素的链接。我通常会隐藏这个元素,但是我想向您展示 tabs 小部件用于标签的结构的一个很好的副作用。创建一个列表,其中每个列表项都包含一个链接,这意味着单击该链接将跳转到文档的该部分,如果该链接指向另一个文件,则浏览器将导航到该文档。这将帮助我从选项卡标题中获得我想要的行为。

应用选项卡

我准备将 tabs 小部件应用到示例中。清单 20-13 显示了script元素中需要的变化。文档中的任何其他地方都不需要更改。

清单 20-13 。创建选项卡小部件

...
<script type="text/javascript">

    $(document).ready(function () {

        var data = [{ "name": "Aster", "product": "aster" },
                    { "name": "Daffodil", "product": "daffodil" },
                    { "name": "Rose", "product": "rose" },
                    { "name": "Peony", "product": "peony" }];

        var elems = $("#flowerTmpl").template({ flowers: data }).filter("*");
        elems.slice(0, 2).appendTo("#row1");
        elems.slice(2, 4).appendTo("#row2");

        var detailsData = [{ name: "Name", hint: "Enter your name" },
                { name: "Street", hint: "Enter your street" },
                { name: "City", hint: "Enter your city" },
                { name: "State", hint: "Enter your state" },
                { name: "Zip", hint: "Enter your zip code" }];

        $("#detailsTmpl").template({ details: detailsData }).filter("*")
            .appendTo("#tab2").clone().appendTo("#tab3")

        $(".fl").removeClass("fl");
        $("#tabs").tabs().find("h2").remove();

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

我删除了用于定位详细信息和送货地址区域内容的fl类,并删除了用于部分标题的h2元素。然后我调用tabs方法,它使用内容元素作为标签的基础,正如你在图 20-9 中看到的。

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

图 20-9 。将选项卡应用于表单

处理按钮按压

为了使表单更容易使用选项卡填写,我为button元素的click事件注册了一个处理程序。在这个处理程序中,我取消了事件的默认操作,并移动到序列中的下一个选项卡,直到到达最后一个选项卡。此时,单击button将表单提交给服务器。清单 20-14 显示了我对script元素添加的内容。

清单 20-14 。使用提交按钮在表单中前进

...
<script type="text/javascript">

    $(document).ready(function () {

        var data = [{ "name": "Aster", "product": "aster" },
                    { "name": "Daffodil", "product": "daffodil" },
                    { "name": "Rose", "product": "rose" },
                    { "name": "Peony", "product": "peony" }];

        var elems = $("#flowerTmpl").template({ flowers: data }).filter("*");
        elems.slice(0, 2).appendTo("#row1");
        elems.slice(2, 4).appendTo("#row2");

        var detailsData = [{ name: "Name", hint: "Enter your name" },
                { name: "Street", hint: "Enter your street" },
                { name: "City", hint: "Enter your city" },
                { name: "State", hint: "Enter your state" },
                { name: "Zip", hint: "Enter your zip code" }];

        $("#detailsTmpl").template({ details: detailsData }).filter("*")
            .appendTo("#tab2").clone().appendTo("#tab3")

        $(".fl").removeClass("fl");
        $("#tabs").tabs().find("h2").remove();

        $("button").button().click(function (e) {
            var tabsElem = $("#tabs");
            var activeTab = tabsElem.tabs("option", "active");
            if (activeTab < tabsElem.find("ul > li").length -1) {
                tabsElem.tabs("option", "active", activeTab + 1)
                e.preventDefault();
            }
        });
    });
</script>
...

我使用active选项来获取活动选项卡的索引,并使用 jQuery 选择器来获取选项卡标题元素的集合,并计算出有多少个。如果用户没有到达最后一个选项卡,那么我设置active选项来前进到序列中的下一个选项卡。只有当用户不在最后一个选项卡上时,我才调用preventDefault方法,这允许表单在选项卡序列的末尾提交。

执行验证

目前,用户可以直接跳到最后一页并提交表单。为了防止这种情况,我将应用一些基本的表单验证。为了使这个例子简单,我将手动处理验证,但是对于真实的项目,我推荐使用验证插件和我在第十三章中描述的技术。清单 20-15 展示了对script元素的修改,以实现一些基本的验证,并防止用户过早跳到 tab 序列的末尾。

清单 20-15 。防止用户跳过带有一些基本验证的选项卡

...
<script type="text/javascript">

    $(document).ready(function () {

        var data = [{ "name": "Aster", "product": "aster" },
                    { "name": "Daffodil", "product": "daffodil" },
                    { "name": "Rose", "product": "rose" },
                    { "name": "Peony", "product": "peony" }];

        var elems = $("#flowerTmpl").template({ flowers: data }).filter("*");
        elems.slice(0, 2).appendTo("#row1");
        elems.slice(2, 4).appendTo("#row2");

        var detailsData = [{ name: "Name", hint: "Enter your name" },
                { name: "Street", hint: "Enter your street" },
                { name: "City", hint: "Enter your city" },
                { name: "State", hint: "Enter your state" },
                { name: "Zip", hint: "Enter your zip code" }];

        $("#detailsTmpl").template({ details: detailsData }).filter("*")
            .appendTo("#tab2").clone().appendTo("#tab3")

        var activePanel;

        $(".fl").removeClass("fl");
        $("#tabs").tabs({
            beforeActivate: function (e, ui) {
                validatePanel(e, ui.oldPanel);
            },
            activate: function (e, ui) {
                activePanel = ui.newPanel;
            }
        }).find("h2").remove();

        function validatePanel(e, panelElem) {
            var inputElems = panelElem.find("input");
            if (panelElem.attr("id") == "tab1" ?
                sumInputElems(inputElems) : countEmptyOrZeroValues(inputElems)) {
                alert("Validation Problem!");
                e.preventDefault();
            }
        }

        function sumInputElems(inputs) {
            var total = 0;
            inputs.each(function (index, elem) {
                total+= Number($(elem).val());
            });
            return total == 0;
        }

        function countEmptyOrZeroValues(inputs) {
            var count = 0;
            inputs.each(function (index, elem) {
                if (elem.value == null || elem.value == "") {
                    count++;
                }
            });
            return count > 0;
        }

        $("button").button().click(function (e) {
            var tabsElem = $("#tabs");
            var activeTab = tabsElem.tabs("option", "active");
            if (activeTab < tabsElem.find("ul > li").length - 1) {
                tabsElem.tabs("option", "active", activeTab + 1)
                e.preventDefault();
            } else {
                validatePanel(e, activePanel);
            }
        });
    });
</script>
...

我使用了两个选项卡事件来获得我想要的效果。当用户从一个选项卡导航到下一个选项卡时,beforeActivated事件很有用,因为它为我提供了一个对即将关闭的选项卡的内容面板的引用,我通过传递给我的处理函数的第二个参数的属性来访问它,该函数是ui对象,如表 20-7 中所述。

表 20-7 。传递给 beforeActivate 和 Activate 事件处理程序的附加对象的属性

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

我使用oldPanel引用来执行验证,并通过调用事件对象上的preventDefaultAction方法来停止向另一个选项卡的转换(如第九章所述)。

这种方法有一个问题,即当用户在完成最后一个选项卡后单击button元素时,不会触发beforeActivate事件,因为表单被提交给了服务器。出于这个原因,我还处理了activate事件,并存储了一个对显示的新选项卡的引用(我通过ui对象的newPanel属性访问它,该属性还定义了表 20-7 中显示的属性)。在允许表单提交给服务器之前,我使用这个引用来执行验证。

我告诉用户验证错误的方法是调用alert函数并在对话框中显示一条消息,如图 20-10 中的所示。显然,在一个真实的项目中,你可以使用验证插件的概要特性,正如我在第十三章中所描述的。

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

图 20-10 。为响应验证错误而显示的警告框

摘要

在本章中,我向您展示了 jQuery UI tabs 小部件。这个小部件提供了丰富而复杂的功能,可以在多种情况下使用。我发现自己经常使用这个小工具。它是灵活的,完全可定制的,用户通常熟悉有选择地显示包含在单个选项卡中的内容的想法,而其他小部件(如 accordion)并不总是这样。在第二十一章中,我向你展示了 datepicker 小部件。

二十一、使用 Datepicker 小部件

本章重点介绍 jQuery UI datepicker 小部件,它提供了一种方便的机制来帮助用户选择日期。众所周知,从用户那里获取日期信息是有问题的,因为可以用多种格式来表示日期。datepicker 小部件可以让用户更容易地选择日期,以一种更一致、更不容易出错的方式,并使用常规文本input元素。表 21-1 对本章进行了总结。

表 21-1 。章节总结

问题解决办法列表
创建弹出 jQuery UI 日期选择器input元素上使用datepicker方法one
创建内嵌日期选择器spandiv元素上使用datepicker方法Two
指定日期选择器显示的日期使用defaultDate设置three
指定当用户选择日期时将被更新的附加元素使用altField设置four
更改导致弹出日期选择器出现的操作使用showOn设置five
指定在 datepicker 触发器按钮中显示的文本使用buttonText设置six
显示图像代替触发按钮使用buttonImagebuttonImageOnly设置seven
限制日期选择使用constrainInputminDatemaxDate设置8, 9
在日期选择器中显示几个月使用numberOfMonths设置10–12
启用下拉菜单来帮助导航到月份和年份使用changeMonthchangeYear设置Thirteen
在日期选择器中显示周信息使用showWeekweekHeader设置Fourteen
用前几个月和后几个月的日期填充日期网格使用showOtherMonthsselectOtherMonths设置Fifteen
在日期选择器的底部显示一个按钮栏使用showButtonBargotoCurrent设置Sixteen
向用户显示格式提示使用appendText设置(或 HTML5 占位符功能)17, 18
以编程方式获取或设置日期使用getDatesetDate方法Nineteen
以编程方式显示或隐藏弹出日期选择器使用showhide方法Twenty
响应用户导航到新的月份或年份使用onChangeMonthYear事件Twenty-one
响应弹出的日期选择器关闭使用onClose事件Twenty-two
本地化日期选择器使用 jQuery UI i8n 支持Twenty-three

创建日期选择器

您可以通过两种方式使用日期选择器。最常见的是使用datapicker方法将小部件附加到input元素。input没有立即的视觉变化,但是当元素获得焦点时(因为用户或者从其他元素切换或者单击input字段),datepicker 弹出来帮助用户选择日期。清单 21-1 演示了这个弹出窗口 datepicker 。

清单 21-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">
        input {width: 200px; text-align: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#datep").datepicker();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <div class="ui-widget">
        <label for="datep">Date: </label><input id="datep"/>
      </div>
    </form>
</body>
</html>

在图 21-1 中,你可以看到聚焦于input元素是如何显示日期选择器的。

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

图 21-1 。当 input 元素获得焦点时,将弹出 datepicker

当显示 datepicker 弹出窗口时,用户可以选择手动输入日期或使用 datepicker 窗口选择日期。当input元素失去焦点或者当用户点击 Enter 或 Escape 键时,datepicker 弹出窗口消失。

创建内嵌日期选择器

使用日期选择器的另一种方法是在内联中使用它。为此,您使用 jQuery 选择一个divspan元素,然后调用datepicker方法。只要基础元素可见,内联 datepicker 就可见。清单 21-2 展示了如何创建一个内嵌的日期选择器 。

清单 21-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">
        input {width: 200px; text-align: left; margin-right: 10px}
        #wrapper > * {float: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#inline").datepicker();
        });
    </script>   
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
        <div id="wrapper" class="ui-widget">
            <label for="datep">Date: </label>
            <input id="datep"/>
            <span id="inline"></span>
        </div>
    </form>
</body>
</html>

在这个例子中,我添加了一个span元素,并将其用作datepicker方法的目标。你可以在图 21-2 中看到效果。

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

图 21-2 。内嵌日期选择器

当您不想使用弹出窗口时,内嵌日期选择器会很有用。在某些应用中,日期非常重要,因此始终显示 datepicker 是有意义的,但在大多数情况下,在需要时隐藏弹出窗口是更明智的做法。隐藏和显示内联日期选择器的问题是,文档的布局必须灵活以适应日期选择器,这可能会导致显示问题。几乎在所有情况下,我发现弹出式日期选择器更有用。

配置日期选择器

如果你以前做过与日期有关的工作,你会明白处理它们是复杂的。这种复杂性反映在 datepicker 小部件支持的大量设置中。在接下来的部分中,我描述了可用于配置 datepicker 的相关设置组。

执行基本配置

表 21-2 描述了执行 datepicker 小工具基本配置的设置。在接下来的小节中,我将向您展示如何使用这些设置。

表 21-2 。基本日期选择器设置

环境描述
altField指定将随数据选择更新的附加字段。
buttonImageOnly指定由buttonImage指定的图像应该包含在img元素中,而不是包含在button中。默认为false
buttonImage指定用于弹出触发器按钮的图像的 URL。默认情况下不使用。
buttonText指定弹出触发器按钮的文本。默认为省略号(...)。
defaultDate设置显示日期选择器时突出显示的日期。
disabled指定最初是否禁用 datepicker 小工具。默认为false
showOn指定显示弹出日期选择器的触发器。默认为focus

指定默认日期

最基本的设置也是最有用的设置之一。defaultDate设置指定显示日期选择器时将显示的日期。如果您没有为defaultDate设置提供值,那么将使用当前日期。(当然,这是用户系统定义的日期。时区、日期线和错误配置都可能给用户呈现与您预期不同的日期。)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示该设置仅在input元素没有value属性时使用。如果有,要么是因为您在文档中包含了value属性,要么是因为用户之前已经做出了选择,那么 datepicker 将忽略该设置。

如果你不想要今天的日期,那么你可以从几种不同的格式中选择来表达你想要开始的日期。表 21-3 显示了您可以使用的格式和值的范围。

表 21-3 。默认日期设置的格式和值

值/格式描述
null使用当前系统日期。
Date对象使用由Date对象表示的值。
+days-days使用从今天起指定天数的日期。例如,+3表示显示三天后的日期,-2表示显示两天前的日期。
+1d +7w -1m +1y使用相对于今天的日期,表示为未来(d)、周(w)、月(m)和年(y)(+)或过去(-)。正值和负值可以混合在一个日期中,因此 2011 年 11 月 12 日使用的值-1d +1m选择日期 2011 年 12 月 11 日。

清单 21-3 展示了如何使用defaultDate设置来指定未来五年的日期。

清单 21-3 。使用默认日期设置

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            defaultDate: "+5y"
        });
    });
</script>
...

我在 2013 年 6 月写这一章,你可以在图 21-3 中看到defaultDate设置的+5y值聚焦于 2018 年 6 月的日期选择器。

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

图 21-3 。使用 defaultDate 设置显示未来日期

如示例所示,您可以省略任何不想更改的间隔,这样就可以使用+5y而不是+0d +0w +0m +5y。您可以混合搭配不同时间间隔的负值和正值,以确定您想要的日期。

指定替代元素

altField设置指定了一个input元素,当您选择日期时,该元素将被更新。这是链接input元素和内嵌日期选择器的最简单的方法。清单 21-4 显示了使用altField设置来显示内嵌日期选择器的选择。

清单 21-4 。将 altField 设置与内联 Datepicker 一起使用

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#inline").datepicker({
            altField: "#datep"
        });
    });
</script>
...

在清单 21-4 中,我使用了一个选择器字符串来标识我想要使用的元素,但是altField设置也将接受一个 jQuery 对象或一个文档对象模型(DOM) HTMLElement对象。这个例子的效果是,input元素在我每次使用 datepicker 进行选择时显示日期,如图 21-4 中的所示。

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

图 21-4 。指定日期选取器将更新的输入元素

管理弹出触发器

showOn设置控制向用户显示弹出日期选择器的原因。该设置有三个允许值。

  • focus:当input元素获得焦点时弹出。这是默认设置。
  • button:点击按钮时弹出。
  • both:点击按钮或输入获得焦点时弹出。

当您使用buttonboth值时,datepicker 小部件会创建一个button元素,并将其添加到文档中的input元素之后。清单 21-5 显示了showOn设置的使用。

清单 21-5 。使用 showOn 设置

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            showOn: "both"
        });
    });
</script>
...

你可以在图 21-5 中看到小部件创建的button元素。因为我在这个例子中使用了both值,所以当用户点击button或者聚焦于input元素时,弹出窗口就会显示出来。

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

图 21-5 。为响应 showOn 设置而添加的按钮

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示date picker 小部件添加的按钮不是 jQuery UI 按钮小部件。如果你想保持按钮的一致性,那么你需要选择button元素并调用 jQuery UI button方法,如第十八章中的所述。

您可以使用buttonImagebuttonText设置来格式化button元素。如果您将buttonImage设置为 URL,datepicker 小部件将使用button中的图像。或者,您可以使用buttonText设置来设置一个短语来替换默认内容(即...)。清单 21-6 显示了buttonText设置的使用。

清单 21-6 。使用按钮文本设置

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            showOn: "both",
            buttonText: "Select"
        });
    });
</script>
...

如果同时使用buttonImagebuttonTextOnly设置,可以完全去掉按钮文本。这会导致 datepicker 向文档添加一个img元素,而不是一个按钮。清单 21-7 提供了一个演示。

清单 21-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">
        input {width: 200px; text-align: left}
        #dpcontainer * {vertical-align: middle}
        #dpcontainer img {width: 35px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#datep").datepicker({
                showOn: "both",
                buttonImage: "right.png",
                buttonImageOnly: true
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <divid="dpcontainer"class="ui-widget">
        <label for="datep">Date: </label><input id="datep"/>
      </div>
    </form>
</body>
</html>

我指定了一个名为right.png的图像,并将buttonImageOnly 设置为true。我还在文档中添加了一些 CSS 样式来控制图像相对于labelinput元素的外观。datepicker 小部件在如何创建img元素方面不是特别聪明,所以我需要进行补偿,使图像的样式与文档的其余部分保持一致。你可以在图 21-6 中看到有图像而没有按钮的效果。

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

图 21-6 。在弹出日期选择器中使用图像而不是按钮

管理日期选择

您通常希望对用户可以使用 datepicker 小部件选择的日期范围应用约束。表 21-4 描述了允许您应用选择约束来引导用户到您可以处理的日期的设置。

表 21-4 。用于管理日期选择的日期选择器设置

环境描述
changeMonthtrue时,日期选择器显示一个下拉菜单,允许直接导航到一个月。默认为false
changeYeartrue时,日期选择器显示一个下拉菜单,允许直接导航到一个年份。默认为false
constrainInputtrue时,将input元素中的字符限制为有效日期中包含的字符。默认是true
hideIfNoPrevNexttrue时,如果相对于显示的时间段,过去或未来没有可选择的日期,则隐藏上一个和下一个按钮,而不是禁用。默认为false
maxDate指定用户可以选择的最晚日期。默认情况下,允许用户选择任何日期。
minDate指定用户可以选择的最早日期。默认情况下,允许用户选择任何日期。
numberOfMonths指定日期选择器显示的月数。默认为1
showCurrentAtPos指定当前或默认月份在多月日期选择器中的显示位置。默认为0
stepMonths指定单击“上一个”和“下一个”按钮时显示跳跃的月数。默认为1
yearRange指定可在通过changeYear设置启用的下拉列表中选择的年份范围。默认显示当前年份的十年前和十年后。

限制输入字符和日期范围

当设置为true时,constrainInput设置将可以输入到input元素中的字符限制为有效日期中包含的字符。字符集取决于您正在使用的本地化配置,我将在“本地化日期选择”一节中对此进行更多讨论如果您没有本地化 datepicker 小部件,那么您可以预期input元素会受到限制,这样用户只能输入数字和/字符。

这个设置并不意味着用户只能输入有效的日期,因为可以输入像99/99/99这样的值,但是它可以帮助减少错误。当showOn设置被设置为button时,该设置的重要性增加,因为当input元素获得焦点时,弹出窗口不会自动出现。用户通常会在出现日期选择器时进行选择,但并不总是意识到按钮会显示选择器。您给用户的每一次直接输入日期的机会都会增加您处理格式错误的值的机会。清单 21-8 显示了constrainInput设置的使用。

清单 21-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="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        input {width: 200px; text-align: left; margin-right: 10px}
        #wrapper > * {float: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#datep").datepicker({
                constrainInput: true,
                minDate: "-3",
                maxDate: "+5"
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <div id="wrapper" class="ui-widget">
        <label for="datep">Date: </label><input id="datep"/><span id="inline"></span>
      </div>
    </form>
</body>
</html>

默认情况下,constrainInput设置是true,所以我也为minDatemaxDate设置添加了值,只是为了让这个例子更有趣一点。这些设置允许我指定用户可以选择的最早和最晚日期。与我在“指定默认日期”一节中展示的defaultDate设置一样,我可以将minDatemaxDate设置的日期指定为null(无日期)、一个Date对象、一个number日期或一个相对日期字符串。在清单 21-8 中,我使用了数字选项来指定相对于今天的天数。在图 21-7 中,您可以看到 datepicker 小部件禁用了任何用户不能选择的日期。

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

图 21-7 。限制用户可以选择的日期

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示注意,上一页和下一页按钮在不需要时会自动禁用。这些按钮位于日期选择器的左上角和右上角,允许用户移动到上个月和下个月。在图 21-7 中,用户可以选择的所有日期都在当月或上月,因此下一步按钮被禁用。在这种情况下,您可以通过将hideIfNoPrevNext设置为true来隐藏而不是禁用按钮。

minDate不需要在过去,maxDate不需要在未来,并且您不必为两个设置都提供值。如果您需要用户选择一个有某种提前期的日期,您可以为minDate设置指定一个未来的日期,以防止选择您需要准备的日期,如清单 21-9 所示。

清单 21-9 。提供一个日期限制来创建一个延迟窗口

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            minDate: "+7"
        });
    });
</script>
...

在本例中,我已经指定用户不能选择从今天起一周内发生的任何日期。没有maxDate值,这意味着可以选择从现在起一周之后的任何未来日期。你可以在图 21-8 中看到结果。请注意,此图中启用了“下一步”按钮(允许用户导航到下个月),但禁用了“上一步”按钮(因为不允许用户选择过去的日期)。

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

图 21-8 。创建开放式日期选择范围

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示minDatemaxDate设置与defaultDate设置协同工作,这意味着您可以指定相对于不是今天的日期的日期范围。

创建多月显示

datepicker 允许您通过numberOfMonths设置指定向用户显示多少个月。您可以指定月数或双元素数组,该数组指定月网格的大小。清单 21-10 显示了基于数组的方法,我发现这种方法最适合内联日期选择器,因为网格通常太大而不能用作弹出窗口(稍后我会解释原因)。

清单 21-10 。使用月数设置

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#inline").datepicker({
            numberOfMonths: [1, 3]
        });
    });
</script>
...

在这个例子中,我指定了一个高一个月宽三个月的网格。你可以在图 21-9 中看到效果。

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

图 21-9 。显示月份的网格

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示二元数组[1, 3]相当于数值3。当您为­numberOfMonths设置提供一个数字时,datepicker 会在一行中显示指定的月数。

我很少在弹出日期选择器中使用这个特性的原因是,大的网格需要假设用户浏览器窗口和显示的大小。datepicker 弹出窗口不是操作系统对话框。它是一个精心格式化的 HTML 元素,作为 HTML 文档的一部分显示。这意味着当一个大的日期选择器显示在一个小屏幕上或一个小浏览器窗口中时,大部分细节被移出了屏幕的边缘。清单 21-11 显示了一个应用于弹出日期选择器的月份网格。

清单 21-11 。使用弹出日期选择器设置月数

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            numberOfMonths: [1, 3]
        });
    });
</script>
...

你可以在图 21-10 中看到结果。不仅许多可用日期对用户隐藏,而且 next 按钮(允许用户推进显示的月份)也不在屏幕上。

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

图 21-10 。显示大的弹出日期选择器

您可以使用showCurrentAtPos设置在多月日期选择器中更改所选日期的位置。从图 21-9 和图 21-10 中可以看到,默认是先显示当前月份,然后是未来的两个月。showCurrentAtPos设置采用一个从零开始的索引值,该值指定当前月份应该显示的位置。如果您需要允许用户选择今天的任意一天,这是一个非常方便的特性。清单 21-12 显示了该设置的使用。

清单 21-12 。使用 showCurrentAtPos 设置

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#inline").datepicker({
            numberOfMonths: 3,
            showCurrentAtPos: 1
        });
    });
</script>
...

我已经指定当前日期应该显示在日期选择器显示的三个月的中间。你可以在图 21-11 中看到结果。

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

图 21-11 。在多月日期选择器中指定当前月份的位置

提供对月份和年份的直接访问

您可以用下拉菜单替换 datepicker 标题中的月份和年份,这些下拉菜单提供了对月份和年份的直接访问。当有很大的日期范围可供选择时,这对于用户来说是一个有用的快捷方式。控制这些功能的设置是changeMonthchangeYear。这些设置的true值启用相应的菜单,菜单可以彼此独立启用。清单 21-13 展示了这些设置的使用。

清单 21-13 。通过下拉菜单直接访问月份和年份

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            changeMonth: true,
            changeYear: true,
            yearRange: "-1:+2"

        });
    });
</script>
...

在这个清单中,我启用了两个下拉菜单。我还使用了yearRange设置来限制用户可以浏览的年份范围。我指定了一个值-1:+2,这意味着用户可以选择从现在开始的一年到未来的两年。因为我在 2013 年写这一章,所以呈现给用户的年份范围是 2012 年到 2015 年。你可以在图 21-12 中看到菜单是如何显示的(以及年份范围是如何出现的)。

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

图 21-12 。为用户提供对月份和年份的直接访问

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示您也可以为yearRange设置提供一个实际年份范围。我可以在图 21-12 中用2012:2015的值得到同样的结果。

管理日期选择器的外观

您可以使用许多设置来定制 datepicker 向用户显示时的外观。对于一般的日期选择目的,您在前面的示例中看到的默认外观通常是合适的,但是调整外观以适应 web 应用的需求的能力非常有用。表 21-5 描述了外观相关的设置。

表 21-5 。用于控制外观的日期选择器设置

环境描述
appendText指定将在文档中插入到input元素之后的格式提示。
closeText指定按钮栏中用于关闭弹出日期选取器的按钮的文本。默认为Done
currentText指定用于按钮栏中返回到当前日期的按钮的文本。默认为Today
duration指定执行由showAnim设置指定的动画的速度或持续时间。默认为normal。我在第三十五章中描述了 jQuery UI 动画效果。
gotoCurrenttrue时,按钮栏中的Today按钮将返回到所选择的日期,而不是今天的日期。默认是false
selectOtherMonthstrue时,可以选择作为showOtherMonths设置结果显示的日期。默认是false
showAnim指定用于显示和隐藏弹出日期选择器的动画。我在第三十五章中描述了 jQuery UI 动画效果。默认为show
showButtonPaneltrue时,日期选择器显示一个按钮栏,允许用户跳转到当前日期,并(当与弹出窗口一起使用时)关闭日期选择器。默认为false
showOptions指定由showAnim设置定义的动画选项。我在第三十五章中描述了 jQuery UI 动画效果。
showOtherMonthstrue时,日期选取器用上个月和后续月份的日期填充日期网格中的空白。默认为false
showWeektrue时,日期选择器显示一个显示周信息的列。默认为true
weekHeader设置通过showWeek设置启用的周列标题。默认为Wk

显示周

对于某些应用来说,知道日期属于一年中的哪一周是非常重要的。例如,在预算管理应用中经常会出现这种情况。jQuery UI datepicker 可以显示周信息,通过showWeekweekHeader设置进行配置,如清单 21-14 所示。

清单 21-14 。在日期选择器中显示周信息

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            showWeek: true,
            weekHeader: "Week"
        });
    });
</script>
...

showWeek设置为true时,日期选择器显示一列显示周数。您可以使用weekHeader设置来更改默认的Wk周栏的标题。在这个例子中,我启用了 week 列,并将标题改为Week。你可以在图 21-13 中看到结果。

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

图 21-13 。在日期选择器中显示周信息

允许月份间出血

默认情况下,datepicker 仅显示当月的日期。这意味着在日期范围之前和之后的日期网格中有空白条目。您可以通过使用showOtherMonth设置的值true来显示上个月和下个月的日期,如清单 21-15 所示。

清单 21-15 。让几个月一个月地过去

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            showOtherMonths: true
        });
    });
</script>
...

你可以在图 21-14 中看到结果。除非selectOtherMonths设置为true,否则不能选择其他月份的日期。

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

图 21-14 。显示前几个月和后几个月的日期

使用按钮栏

true时,showButtonBar设置启用日期选择器窗口底部的按钮栏。使用弹出日期选择器时,按钮栏包含TodayDone按钮。Today按钮跳回当前日期,而Done按钮关闭弹出窗口。在图 21-15 中可以看到按钮。当是内嵌日期选择器的一部分时,只显示Today按钮。

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

图 21-15 。显示按钮栏

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示您可以使用currentTextcloseText设置更改用于TodayDone按钮的文本。

true时,gotoCurrent设置会将日期选择器返回到当前选择的日期,而不是今天的日期。当您使用defaultDate设置配置了日期选择器时,这很有用。如果日期选择的目的与历史或未来事件相关,则返回当前日期并不总是有意义的。清单 21-16 包含了一个例子。

清单 21-16 。使用 gotoCurrent 设置

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            showButtonPanel: true,
            gotoCurrent: true,
            defaultDate: "+1m +1y"
        }).val("12/25/2012");
    });
</script>
...

请注意,gotoCurrent设置使按钮转到选定的日期。在清单 21-16 中,日期将取自input元素的value属性,但是如果用户选择了另一个日期,然后再次打开日期选择器,按钮将返回到用户选择的日期,而不是您指定的日期。

向用户提供格式提示

您可以使用appendText设置来为用户提供关于您期望的日期格式的提示。清单 21-17 展示了。

清单 21-17 。使用 appendText 设置提供格式提示

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").datepicker({
            appendText: "(mm/dd/yyyy)"
        });
    });
</script>
...

日期选择器将您指定的文本插入到文档中,如图图 21-16 所示。

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

图 21-16 。使用 appendText 设置向用户提供格式提示

当您依靠按钮来显示弹出的日期选择器时,此设置最有用。当用户不用日期选择器就可以自由输入文本时,那么您给她关于格式的提示可以显著减少您必须处理的错误(这对您来说是好的,对用户来说也不那么令人沮丧)。最近,我开始为input元素使用 HTML5 placeholder属性,作为对日期选择器appendTo设置的一个更简洁的替代。清单 21-18 展示了。

清单 21-18 。使用 HTML5 占位符属性提供格式提示

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#datep").attr("placeholder", "mm/dd/yyyy").datepicker();
    });
</script>
...

显然,这要求用户拥有支持 HTML5 的浏览器,但效果更优雅。用户看到的提示是灰色的文本,当他开始输入时就会消失。我更喜欢这样,因为它将格式提示与input元素更紧密地联系在一起,并且它不需要文档布局中的空间。你可以在图 21-17 中看到占位符是如何在谷歌浏览器中显示的。

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

图 21-17 。使用 HTML5 占位符作为格式提示

使用日期选择器方法

datepicker 小部件支持表 21-6 中所示的方法。

表 21-6 。手风琴方法

方法描述
datepicker("destroy")从基础元素中移除 datepicker
datepicker("disable")禁用日期选择器
datepicker("enable")启用日期选择器
datepicker("option")为 datepicker 设置一个或多个选项
datepicker("isDisabled")如果日期选择器被禁用,则返回true
datepicker("hide")隐藏弹出式日期选择器
datepicker("show")显示弹出的日期选择器
datepicker("refresh")刷新 datepicker 以反映基础元素中的更改
datepicker("getDate")从 datepicker 获取选定的日期
datepicker("setDate", date)为日期选择器设置选定的日期

以编程方式获取和设置日期

当我使用多个内联日期选择器来允许用户选择日期范围时,我发现getDatesetDate方法最有用。在这种情况下,我不想在input元素中显示选择的日期。我只想显示第一次和第二次约会之间的天数。清单 21-19 演示了。

清单 21-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="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        input {width: 200px; text-align: left; margin-right: 10px}
        #wrapper > * {float: left}
        #result {margin: auto; padding: 10px; width: 200px; clear: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {

            $("#result").hide();

            $("#dateStart, #dateEnd").datepicker({
                minDate: "-7d",
                maxDate: "+7d",
                onSelect: function(date, datepicker) {
                    if (datepicker.id == "dateStart") {
                        $("#dateEnd").datepicker("setDate", date)
                            .datepicker("enable").datepicker("option", "minDate", date)
                    }

                    if (!$("#dateEnd").datepicker("isDisabled")) {
                        var startDate = $("#dateStart").datepicker("getDate");
                        var endDate = $("#dateEnd").datepicker("getDate");
                        var diff = endDate.getDate() - startDate.getDate();
                        $("#dayCount").text(diff).parent().show();
                    }
                }

            }).filter("#dateEnd").datepicker("disable");
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <div id="wrapper" class="ui-widget">
        <label for="dateStart">Start: </label><span id="dateStart"></span>
        <label for="dateEnd">End: </label><span id="dateEnd"></span>
      </div>
      <div id="result" class="ui-widget">
        Number of Days: <span id="dayCount"></span>
      </div>
    </form>
</body>
</html>

在清单 21-19 的中有两个日期选择器,第二个在文档第一次加载时被禁用。我使用onSelect事件(当选择日期时触发)来响应用户选择日期。当用户在第一个日期选择器中做出选择时,我使用setDate方法准备第二个日期选择器,使用getDate方法从两个日期选择器中获取日期,以便计算出第一个和第二个选择的日期之间的天数(为了使这个例子简单,我做了一个比较,假设两个日期在同一个月)。您可以在图 21-18 的中看到该文档是如何在浏览器中显示的。

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

图 21-18 。使用 getDate 和 setDate 方法

以编程方式显示和隐藏弹出日期选择器

您可以使用showhide方法以编程方式控制弹出日期选择器在屏幕上的出现。如果您希望将 datepicker 与除了 datepicker 小部件创建的input元素或button的焦点之外的其他东西相关联,这将非常有用。我不太喜欢让日期选择器在文档中创建一个按钮,所以我偶尔会发现自己使用这些方法从自己添加的按钮中控制日期选择器,如清单 21-20 所示。

清单 21-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="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <style type="text/css">
        input {width: 200px; text-align: left; margin-right: 10px}
        #wrapper > * {float: left}
        label {padding: 4px; text-align: right; width: auto}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {

            $("#datep").datepicker();

            $("button").click(function(e) {
                e.preventDefault();
                $("#datep").datepicker("show");
                setTimeout(function() {
                    $("#datep").datepicker("hide");
                }, 5000)
            })

        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <div id="wrapper" class="ui-widget">
        <label for="datep">Date: </label><input id="datep"/><span id="inline"></span>
        <button>Datepicker</button>
      </div>
    </form>
</body>
</html>

当按钮被点击时,我调用 datepicker show方法。我不经常使用hide方法,因为我希望用户在做出选择后能够关闭弹出窗口,但是为了完整起见,我使用了setTimeout函数,这样在按钮被按下 5 秒后弹出窗口就会被关闭。

使用 Datepicker 事件

像所有 jQuery UI 小部件一样,datepicker 支持一组事件,允许您接收重要更改的通知。表 21-7 描述了这些事件。

表 21-7 。日期选择器事件

事件描述
create创建 datepicker 时触发
onChangeMonthYear当用户移动到不同的月份或年份时触发
onClose关闭弹出日期选择器时触发
onSelect当用户选择日期时触发

我不打算再次演示onSelect方法,因为我已经在几个例子中使用过它,包括“以编程方式获取和设置日期”一节中的例子传递给该事件处理函数的参数是所选日期和触发该事件的 datepicker 的字符串表示形式。

响应月份或年份的变化

onChangeMonthYear事件允许您在用户选择新的月份或年份时做出响应,无论是通过changeMonthchangeYear设置启用的下拉菜单,还是通过上一个和下一个按钮。清单 21-21 展示了如何使用这个事件来保持两个日期选择器的一致性。

清单 21-21 。使用 onChangeMonthYear 事件

<!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">
        input {width: 200px; text-align: left; margin-right: 10px}
        #wrapper > * {float: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {

            $("#dateStart, #dateEnd").datepicker({
                onSelect: function(date, datepicker) {
                    if (datepicker.id == "dateStart") {
                        $("#dateEnd").datepicker("setDate", date)
                    }
                },
                onChangeMonthYear: function(year, month, datepicker) {
                    if (datepicker.id == "dateStart") {
                        var newDate = new Date();
                        newDate.setMonth(month -1);
                        newDate.setYear(year);
                        $("#dateEnd").datepicker("setDate", newDate);
                    }
                }
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <div id="wrapper" class="ui-widget">
        <label for="dateStart">Start: </label><span id="dateStart"></span>
        <label for="dateEnd">End: </label><span id="dateEnd"></span>
      </div>
    </form>
</body>
</html>

该事件函数的三个参数是显示的年份、显示的月份和触发事件的日期选择器。对于弹出日期选择器,this变量被设置为input元素。当用户在第一个日期选择器上导航到新的月份或年份时,我在第二个日期选择器上设置日期以保持它们同步。

注意,datepicker 小部件将一月表示为一月,而 JavaScript 对象Date使用 0。这就是为什么我要做这样一个丑陋的调整

...
newDate.setMonth(month -1);
...

当我创建我想要在第二个日期选择器中显示的日期时。

响应弹出关闭

您可以使用onClose方法来响应弹出的日期选择器被关闭。即使用户没有选择日期,也会触发此事件。处理函数的参数是日期的字符串表示形式(如果用户没有进行选择就关闭了 datepicker,则为空字符串)和触发事件的 datepicker。清单 21-22 显示了对此事件的简单响应。

清单 21-22 。使用 onClose 事件

<!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">
        input {width: 200px; text-align: left; margin-right: 10px}
        #wrapper > * {float: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#datep").datepicker({
                onClose: function(date, datepicker) {
                    if (date != "") {
                        alert("Selected: " + date);
                    }
                }
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <div id="wrapper" class="ui-widget">
        <label for="datep">Date: </label><input id="datep"/>
      </div>
    </form>
</body>
</html>

在清单 21-22 中,我向用户显示了一个警告框,提示用户做出选择。我必须承认,我从来没有发现自己在一个真实的项目中使用这个事件;我认为最有用的是onSelect事件。

本地化日期选择

jQuery UI datepicker 全面支持世界各地使用的不同日期格式。要使用它们,您需要将一个额外的 JavaScript 文件导入到您的文档中,并告诉 datepicker 您想要使用哪个区域设置。清单 21-23 提供了一个例子。

清单 21-23 。使用本地化的日期选择器

<!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>
    <script src="jquery-ui-i18n.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">
        input {width: 200px; text-align: left; margin-right: 10px}
        #wrapper > * {float: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#inline").datepicker($.datepicker.regional["es"]);
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <form method="post" action="http://node.jacquisflowershop.com/order">
      <div id="wrapper" class="ui-widget">
        <label for="datep">Date: </label><input id="datep"/><span id="inline"></span>
      </div>
    </form>
</body>
</html>

jquery-ui-i18n.js文件可以在你在第十七章中创建的自定义 jQuery UI 下载的development-bundle/ui/i18n文件夹中找到。将该文件复制到主 jQuery 和 jQuery UI 脚本文件旁边,并将以下内容添加到文档中:

...
<script src="jquery-ui-i18n.js" type="text/javascript"></script>
...

您可以在创建日期选取器时指定要使用的区域设置,如下所示:

...
$("#inline").datepicker($.datepicker.regional["es"]);
...

这是一种混乱的语法,但是它允许您指定您想要的本地化格式。在本例中,我指定了es,这意味着我将使用西班牙日期格式。你可以在图 21-19 中看到结果。

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

图 21-19 。本地化日期显示

我对本地化的建议是,要么做好,要么干脆不做。这意味着远远超越日期格式,向用户呈现一个完全遵循语言、地址、性别、货币、时间和所有其他当地惯例的界面。如果您只本地化 web 应用的一部分或者不一致地遵循约定,用户会觉得不和谐。为了正确地本地化一个应用,你应该雇佣一个专门从事这项工作的个人或公司。出错的途径太多了,如果没有专业人士的支持,你注定会失败。

如果你发现自己试图使用谷歌翻译来本地化一个应用(这并不罕见),那么我建议你只使用美国英语和美国本地化惯例来交付应用。这将您的客户群限制在那些熟悉拼写、日期、货币等美国变体的人,但至少您将避免在尝试临时本地化时几乎总是出现的火车失事。

摘要

在本章中,我向您展示了 jQuery UI datepicker 小部件的工作原理,您可以使用它来帮助用户选择日期。datepicker 是一个灵活的小部件,允许您定制日期选择的方式以及 datepicker 的外观。我自己使用日期选择器的经验是,当我向用户请求日期信息时,它们对于减少我必须处理的格式问题的数量是非常宝贵的。在第二十二章中,我向你展示了 jQuery UI 对话框和微调控件。

二十二、使用对话框和微调器小部件

在这一章中,我将描述 jQuery UI 对话框和 spinner 小部件。表 22-1 提供了本章的总结。

表 22-1 。章节总结

问题解决办法列表
创建 jQuery UI 对话框选择一个具有title属性的div元素,并调用dialog方法one
防止对话框一创建就显示autoOpen设置为falseTwo
防止用户调整对话框的大小resizable设置为falsethree
聚焦于对话框中的一个元素设置autofocus属性four
更改对话框的初始位置使用position设置five
向对话框中添加一个或多个按钮使用buttons设置six
在对话框按钮上显示图标使用icons设置seven
允许用户移动对话框使用draggable设置eight
创建模型对话框modal设置为true9, 10
以编程方式打开和关闭对话框使用opencloseisOpen方法Eleven
阻止对话框关闭beforeClose事件的处理函数中返回falseTwelve
响应用户移动或改变对话框的大小响应dragStartdragStopdragresizeStartresizeStopresize事件Thirteen
创建一个 jQuery UI 微调器选择一个input元素并调用spinner方法14–16
配置基本微调器行为使用minmaxsteppage设置Seventeen
更改用于微调按钮的图标使用icons属性Eighteen
控制按住微调按钮时的变化率使用incremental设置Nineteen
更改微调器编号的格式使用culturenumberFormat设置Twenty
以编程方式更改微调器值调用pageDownpageUpstepDownstepUp方法Twenty-one
响应微调器值的变化处理微调器事件Twenty-two

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

当我写这本书的第一版时,spinner 小部件还不存在。在 jQuery UI 版本中,对话窗口小部件和 API(应用编程接口)已经更新。有一些新的对话框特性:一个appendTo设置,指定对话框元素在 DOM(文档对象模型)中的位置;支持在对话框元素上设置焦点;position选项已更改为使用我在第十九章的中描述的格式;并且支持在对话框按钮中显示图标。一些功能也被删除了:?? 和 ?? 设置。

使用 jQuery UI 对话框小部件

jQuery UI dialog 小部件创建一个带有标题和内容区域的浮动窗口,类似于您可能在本地应用中看到的那种对话框。对话框有助于将用户的注意力集中在重要的事件或消息上。与任何可能模糊文档内容的元素一样,对话框必须谨慎使用,只有当在文档布局中显示内容不可行时才使用。

创建对话框

对话框小部件是通过选择一个div元素,然后在生成的jQuery对象上调用dialog方法来创建的。对话框小部件需要特定的 HTML 元素结构才能操作,尽管这种结构比选项卡小部件需要的要简单。清单 22-1 显示了一个包含所需元素的文档,它创建了一个对话框。

清单 22-1 。使用 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.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"/>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#dialog").dialog();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="dialog" title="Dialog Box">
        This is the content that will be displayed in the dialog box. This <b>content</b>
        can be <em>styled</em>.
    </div>
</body>
</html>

对话框小部件需要一个具有title属性的div元素。该属性的值用作对话框的标题栏。div元素的内容被用作对话框的内容,如清单 22-1 所示,该内容可以包含其他元素。当您在没有设置的情况下调用dialog方法时,正如我在清单中所做的,对话框会立即出现。图 22-1 显示了浏览器如何显示对话框。

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

图 22-1 。简单的对话框

对话框小部件是通过巧妙使用 HTML 元素而不是通过操作系统创建的。这意味着 jQuery UI 对话框的行为方式与本地对话框不同。例如,它不会显示在操作系统的打开窗口列表中,并且可以调整浏览器窗口的大小,以便隐藏部分(或全部)jQuery UI 对话框。

也就是说,jQuery UI 团队在尽可能完善对话框功能方面做得很好。通过单击标题并拖动,用户可以在浏览器窗口中重新定位对话框。该对话框可以调整大小,并可以通过单击右上角的关闭按钮来关闭。而且,由于 jQuery UI 对话框小部件是由 HTML 构建的,它使用我在第十七章的中选择的 jQuery UI 主题进行样式化,并且可以显示复杂和样式化的 HTML 内容。

在详细介绍小部件支持的设置、方法和事件之前,我想演示一下对话框的常见用法。当您调用不带参数的dialog方法时,正如我在第一个例子中所做的,对话框会立即出现,但这通常并不方便。更常见的情况是,您希望在文档加载时创建对话框(以便用户看不到元素结构),然后在以后响应事件时显示对话框。清单 22-2 展示了如何做到这一点。

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

            $("#dialog").dialog({
                autoOpen: false
            });

            $("button").button().click(function(e) {
                $("#dialog").dialog("open")
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="dialog" title="Dialog Box">
      This is the content that will be displayed in the dialog box. This <b>content</b>
      can be <em>styled</em>.
    </div>
    <button>Show Dialog</button>
</body>
</html>

您使用autoOpen设置来防止对话框立即出现。当该设置为false时,HTML 元素结构对用户隐藏,但不显示对话框。当你准备好显示对话框时,你可以调用open方法。你可以在图 22-2 中看到这是如何工作的。

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

图 22-2 。推迟对话框的出现

配置对话框

对话框小部件支持一系列设置,允许您自定义向用户显示对话框的方式。我在上一节向您展示了autoOpen设置,但是还有其他设置,如表 22-2 中所述。

表 22-2 。对话框设置

环境描述
appendTo指定对话框应该追加到的元素。
autoOpentrue时,对话框在用dialog方法创建后立即显示。默认是true
buttons指定要添加到对话框中的一组按钮,以及单击这些按钮时将调用的功能。默认情况下不使用按钮。
closeOnEscapetrue时,按退出键关闭对话框。默认为true
draggabletrue时,用户可以点击对话框标题并拖动以在浏览器中移动对话框。默认为true
height以像素为单位指定对话框的初始高度。默认值是auto,它允许对话框自行调整大小。
hide指定用于隐藏对话框的动画效果。有关 jQuery UI 效果的详细信息,请参见第三十五章。
maxHeight指定对话框的最大高度(以像素为单位)。默认为false,表示没有大小限制。
maxWidth指定对话框的最大宽度(以像素为单位)。默认为false,表示没有大小限制。
minHeight指定对话框的最小高度(以像素为单位)。默认值为false,这意味着没有最小大小限制。
minWidth指定对话框的最小宽度(以像素为单位)。默认值为false,这意味着没有最小大小限制。
modaltrue时,对话框是模态的,用户不能与文档交互,直到对话框关闭。默认为false
position指定对话框的初始位置。
resizabletrue时,对话框显示一个拖动手柄,允许用户调整对话框的大小。默认为true
show指定用于显示对话框的动画效果。有关 jQuery UI 效果的详细信息,请参见第三十五章。
title指定对话框的标题。
width以像素为单位指定对话框的初始宽度。默认值是auto,它允许对话框自行调整大小。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示 jQuery UI 1.10 增加了appendTo选项,允许指定对话框将要追加到的元素。另一个新特性是对话框也将自动聚焦于内容元素。(我将在本章的后半部分演示这些特性)。其他变化包括指定position设置值的方式的变化,以及删除stackzIndex配置选项。

配置基本对话框外观

title设置允许你从没有title属性的div元素创建一个对话框。如果您无法控制要在对话框中使用的元素的生成,这将非常有用。清单 22-3 显示了title设置的应用。

清单 22-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"/>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#dialog").dialog({
                title: "Hello",
                resizable: false
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="dialog">
      This is the content that will be displayed in the dialog box. This <b>content</b>
      can be <em>styled</em>.
    </div>
</body>
</html>

在这个例子中,我也应用了resizable设置。此设置防止用户调整对话框的大小。我通常将resizable设置为true,因为我喜欢让用户有机会调整对话框的大小以适应内容。你可以在图 22-3 的例子中看到浏览器是如何显示对话框的。

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

图 22-3 。带有自定义标题的对话框,没有调整大小的拖动手柄

对话框将自动聚焦于它找到的第一个具有autofocus属性的内容元素,这在使用对话框小部件请求用户输入时很有用,如清单 22-4 所示。

清单 22-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"/>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#dialog").dialog({
                title: "Hello",
                resizable: false
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="dialog">
      This is the content that will be displayed in the dialog box. This <b>content</b>
      can be <em>styled</em>.
        <p>Name: <input id="name"/> City: <input id="city" autofocus="autofocus" /></p>
    </div>
</body>
</html>

我已经为对话框的内容添加了input元素,其中第二个元素具有autofocus属性。你可以在图 22-4 中看到对话框组件是如何关注这个元素的。

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

图 22-4 。自动聚焦属性的效果

设置对话框的位置

position设置允许您指定对话框在浏览器窗口中的显示位置。这个位置用我在第十九章中描述的自动完成弹出窗口的相同属性和值来表示,我在表 22-3 中又重复了一遍。

表 22-3 。位置属性

名字描述
my指定将用于确定位置的对话框部分
at指定对话框将相对于其定位的目标元素部分
of指定对话框将相对于其定位的目标元素;如果省略,这就是body元素
collision指定当对话框溢出窗口时,应如何调整对话框的位置

使用指定水平和垂直位置的值设置myat属性,用空格分隔。水平值为leftrightcenter,垂直值为topbottomcenter。你可以在清单 22-5 中看到我如何设置这些属性。(你可以在第十九章中了解其他职位属性。)

清单 22-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"/>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#dialog").dialog({
                title: "Positioned Dialog",
                position: {
                    my: "left top",
                    at: "left top"
                }
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="dialog">
      This is the content that will be displayed in the dialog box. This <b>content</b>
      can be <em>styled</em>.
    </div>
</body>
</html>

我已经定位了对话框,使其左上边缘与其父元素(默认情况下是body元素)的左上边缘在一起。你可以在图 22-5 中看到对话框的位置。

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

图 22-5 。指定对话框的位置

向对话框添加按钮

您可以使用buttons设置向 jQuery UI 对话框添加按钮。这个设置的值是一个对象数组,每个对象都有textclick属性。text属性的值被用作按钮的标签,并且您提供了一个函数作为click属性的值,该函数将在按钮被单击时被调用。清单 22-6 显示了这个设置的用法。

清单 22-6 。向对话框添加按钮

...
<script type="text/javascript">
    $(document).ready(function() {
        $("#dialog").dialog({
            title: "Dialog",
            buttons: [{text: "OK", click: function() {/* do something */}},
                      {text: "Cancel", click: function() {$(this).dialog("close")}}]

        });
    });
</script>
...

在这个脚本中,我添加了两个按钮。“确定”按钮的功能不做任何事情,但是对于“取消”按钮,我关闭了对话框。注意,我在 jQuery 选择器的Cancel函数中使用了this变量。这被设置为用于创建对话框的div元素。你可以在图 22-6 中看到按钮是如何显示的。这个例子使用了close方法,它关闭了对话框。我将在本章的后面描述对话方法。

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

图 22-6 。向 jQuery UI 对话框添加按钮

从 jQuery UI 版本 1.10 开始,您可以通过向定义每个按钮的对象添加一个icons属性来为对话框中的按钮指定图标,如清单 22-7 所示。

清单 22-7 。向对话框小部件中的按钮添加图标

...
<script type="text/javascript">
    $(document).ready(function () {
        $("#dialog").dialog({
            title: "Dialog",
            buttons: [{
                text: "OK",
                click: function () {/* do something */ },
                icons: {
                    primary: "ui-icon-star",
                    secondary: "ui-icon-circle-arrow-e"
                }
            },{ text: "Cancel", click: function () { $(this).dialog("close") }}]
        });
    });
</script>
...

icons属性设置为一个对象,该对象定义了名为primarysecondary的属性,这两个属性定义了按钮文本左侧和右侧的图标。这些属性用于以与按钮部件相同的方式指定图标,如第十八章中的所述。你可以在图 22-7 的中看到列表增加的效果。

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

图 22-7 。在对话框按钮中使用图标

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示通过在定义按钮的对象(不是icons对象)上定义一个名为showText的属性,并将其设置为false,可以禁用对话框按钮中的文本。

拖动对话框

draggable设置决定了用户是否可以在浏览器窗口中拖动对话框。该设置默认为true,我建议您保持该设置不变。它允许用户看到底层内容。如果您正在显示一个对话框来表达某种错误或问题,这可能特别重要。如果draggable设置为false,那么用户将无法重新定位对话框。

当你在同一个窗口中使用多个对话框时,draggable设置也很重要。我不建议这样做,但是如果你一定要显示对话框,你需要确保用户可以排列它们,以便它们都可以被阅读。在小屏幕上,它们倾向于堆叠在一起,如清单 22-8 所示。

清单 22-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="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function () {
            $(".dialog").dialog({
                draggable: true
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="d1" class="dialog" title="First Dialog">
      This is the first dialog
    </div>
    <div id="d2" class="dialog" title="Second Dialog">
      This is the second dialog
    </div>
    <div id="d3" class="dialog" title="Third Dialog">
      This is the third dialog
    </div>
</body>
</html>

我在这个文档中创建了三个对话框,默认的位置是堆叠在一起的。将draggable设置为true可以移动对话框,如图图 22-8 所示。

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

图 22-8 。拖动对话框

创建模式对话框

一个模态对话框 阻止用户与文档中的元素交互,直到对话框被关闭。modal设置的值true创建一个模态对话框,如清单 22-9 所示。

清单 22-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="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#dialog").dialog({
                buttons: [{text: "OK", click: function() {$(this).dialog("close")}}],
                modal: true,
                autoOpen: false
            })

            $("#show").button().click(function() {
                $("#dialog").dialog("open");
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="dialog" title="Modal Dialog">
      This is a modal dialog. Press OK to continue.
    </div>
    <button id="show">Show Dialog</button>
</body>
</html>

在清单 22-9 中,我创建了一个用户最初看不到的模态对话框。该对话框显示为对点击按钮的响应,你可以在图 22-9 中看到效果。这个例子依赖于显示和关闭对话框的openclose方法。我将在本章后面解释对话框小部件支持的所有方法。

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

图 22-9 。显示模式对话框

当显示一个模态对话框时,jQuery UI 在对话框的后面和文档的前面放置一个暗色层。在对话框关闭之前,文档不会返回到原始状态。在这个例子中,我为用户提供了一个OK按钮来完成这个任务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示当选择你已经添加到文档中的按钮来显示对话框时,注意不要使用$("button")如果你也在对话框中添加按钮的话。这个选择器匹配你已经添加的按钮那些由dialog方法创建的按钮,这意味着对话框按钮将以与文档中的按钮相同的点击处理程序结束,而不是由buttons设置指定的处理程序。

在模式对话框中显示窗体

模态对话框的好处是它能集中用户的注意力。您可以通过在模态对话框中显示表单来利用这一点,如清单 22-10 所示。

清单 22-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>
    <script src="handlebars.js"></script>
    <script src="handlebars-jquery.js"></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">
        #dialog input {width: 150px; margin: 5px; text-align: left}
        #dialog label {width: 100px}
        table {border-collapse: collapse; border: thin solid black; margin: 10px}
        #placeholder {text-align: center}
        #show {margin: 10px}
        td, th {padding: 5px; width: 100px}
    </style>
    <script id="rowTmpl" type="text/x-handlebars-template">
        <tr><td>{{product}}</td><td>{{color}}</td><td>{{count}}</td></tr>
    </script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#dialog").dialog({
                buttons: [{ text: "OK", click: addDataToTable }],
                modal: true,
                autoOpen: false,
                width: 340
            })

            $("#show").button().click(function () {
                $("#dialog").dialog("open");
            })

            function addDataToTable() {
                var data = {
                    product: $("#product").val(),
                    color: $("#color").val(),
                    count: $("#count").val()
                }
                $("#placeholder").hide();
                $("#rowTmpl").template(data).filter("*").appendTo("#prods tbody");
                $("#dialog").dialog("close");
            }
        });
    </script>
</head>
<body>
    <h1>Jacqui"s Flower Shop</h1>
    <div id="dialog" title="Enter Details" class="ui-widget">
        <div><label for="product">Product: </label><input id="product" /></div>
        <div><label for="color">Color: </label><input id="color" /></div>
        <div><label for="count">Quantity: </label><input id="count" /></div>
    </div>
    <table id="prods" class="ui-widget" border="1">
        <tr><th>Product</th><th>Color</th><th>Quantity</th></tr>
        <tr id="placeholder"><td colspan=3>No Products Selected</td></tr>
    </table>
    <button id="show">Add Product</button>
</body>
</html>

在清单 22-10 中,我在div元素中定义了一组input元素,用来创建模态对话框。当用户单击文档中的按钮时,会显示对话框并从用户那里收集数据。当用户单击 OK 按钮时(我使用buttons设置定义了这个按钮),我从input元素中收集值,并使用一个数据模板为 HTML 表格生成一个新行。你可以在图 22-10 中看到顺序。

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

图 22-10 。使用模态对话框捕捉用户的输入

我试图保持这个例子的简单,但是你可以很容易地应用我在第十三章向你展示的验证技术来降低数据错误的风险,并且你可以使用我在第十四章和第十五章向远程服务器提交用户输入的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 注意在模态对话框中显示一个表单只对简单表单有用。如果您发现自己试图将标签页或折叠页与模态对话框结合在一起,那么您就有混淆和惹恼用户的风险。如果一个表单代表了大量的填写工作,那么它就应该被恰当地集成到文档本身中。

使用对话方法

jQuery UI 对话框小部件支持表 22-4 中描述的方法。

表 22-4 。对话方式

方法描述
dialog("destroy")从基础元素中移除对话框小部件
dialog("option")更改一个或多个设置
dialog("close")关闭对话框
dialog("isOpen")如果对话框可见,返回true
dialog("moveToTop")将对话框移动到堆栈顶部
dialog("open")向用户显示对话框

如您所料,这些方法中的大多数都允许您以编程方式管理对话框。当然,我发现自己最常用的方法是openclose 。清单 22-11 展示了这些方法。

清单 22-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="styles.css"/>
    <link rel="stylesheet" type="text/css" href="jquery-ui-1.10.3.custom.css"/>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#d1, #d2").dialog({
                autoOpen: false,
            });

            $("#t1, #t2").button().click(function (e) {
                var target = this.id == "t1" ? "#d1" : "#d2";
                if ($(target).dialog("isOpen")) {
                    $(target).dialog("close")
                } else {
                    $(target).dialog("open")
                }
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div id="d1" class="dialog" title="First Dialog" class="ui-widget">
        This is the first dialog
    </div>
    <div id="d2" class="dialog" title="Second Dialog" class="ui-widget">
        This is the second dialog
    </div>
    <div>
        <button id="t1">Toggle Dialog 1</button>
    </div>
    <button id="t2">Toggle Dialog 2</button>
</body>
</html>

这个文档包括两个button元素,用于切换两个对话框的可见性。使用isOpen方法评估每个对话框的可见性。图 22-11 显示了浏览器中显示的文档,两个对话框都可见。

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

图 22-11 。使用窗口小部件方法切换对话框的可见性

使用对话框事件

jQuery UI 对话框小部件支持表 22-5 中描述的事件。我将在接下来的章节中描述一些更有用的事件。

表 22-5 。对话事件

事件描述
create当对话框小部件应用于底层 HTML 元素时触发
beforeClose当对话框即将关闭时触发;从处理函数返回false会强制对话框保持打开
open当对话框打开时触发
focus当对话框获得焦点时触发
dragStart当用户开始拖动对话框时触发
drag拖动对话框时,每次鼠标移动都会触发
dragStop当用户完成拖动对话框时触发
resizeStart当用户开始调整对话框大小时触发
resize调整对话框大小时,每次鼠标移动都会触发
resizeStop当用户完成调整对话框大小时触发
close当对话框关闭时触发

保持对话打开

事件允许您接收用户请求关闭对话框的通知。这可能是因为用户按了退出键(如果closeOnEscape设置是true),点击了对话框右上角的关闭图标,或者点击了您通过buttons设置添加的按钮。

大多数情况下,你应该尊重用户的意愿,允许对话框关闭,但也有少数情况下,你需要用户先使用对话框执行一些动作,或者,如清单 22-12 所示,你需要对话框显示一段时间,然后才允许用户继续。

清单 22-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">
        input {width: 150px}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {

            var canClose = false;
            var delay = 15;

            $("#dialog").dialog({
                modal: true,
                autoOpen: false,
                beforeClose: function() {
                    return canClose;
                },
                open: function() {
                    var count = delay;
                    var intID = setInterval(function() {
                        count--;
                        $("#time").text(count);
                        if (count == 0) {
                            clearInterval(intID)
                            canClose = true;
                            $("#dialog").dialog("close")
                        }
                    }, 1000)
                }
            })

            $("button").click(function(e) {
                $("#dialog").dialog("open")
            })

        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>

    <div class="ui-widget">
        <label for="user">Username: </label><input id="user"/>
        <label for="pass">Password: </label><input id="pass"/>
        <button id="send">Login</button>
    </div>
    <div id="dialog" title="Wrong Password">
        The password you entered was incorrect. Please try again in
        <span id="time">15</span> seconds.
    </div>
</body>
</html>

在清单 22-12 中,我定义了一对input元素来收集用户的用户名和密码。然而,用户输入什么并不重要,因为我通过显示一个错误的密码模式对话框来响应被点击的Login按钮。

我通过启动一个从 15 秒倒计时的重复函数来响应open事件。在此期间,我使用beforeClose事件来阻止用户关闭对话框。在 15 秒结束时,我调用close方法并关闭对话框。通过组合openbeforeClose事件,我可以确保用户不会立即尝试其他用户名或密码组合(至少不会在不重新加载 HTML 文档的情况下尝试)。

响应大小和位置的变化

对话框小部件提供了一组全面的事件,用于在调整对话框大小或拖动对话框时对其进行跟踪。这些是通常不需要的事件,但是在那些能够跟踪变更变得很重要的罕见情况下,这些事件是很方便的。清单 22-13 演示了使用dragStartdragStop事件在对话框被拖动时禁用文档中的inputbutton元素。

清单 22-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">
        input {width: 150px; text-align: left}
    </style>
    <script type="text/javascript">
        $(document).ready(function() {

            $("#dialog").dialog({
                autoOpen: true,
                dragStart: function() {
                    $("input, #send").attr("disabled", "disabled")
                },
                dragStop: function() {
                    $("input, #send").removeAttr("disabled")
                }
            })

            $("button").click(function(e) {
                $("#dialog").dialog("open")
            })
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>

    <div class="ui-widget">
        <label for="user">Username: </label><input id="user"/>
        <label for="pass">Password: </label><input id="pass"/>
        <button id="send">Login</button>
    </div>
    <div id="dialog" title="Wrong Password">
        The password you entered was incorrect. Please try again in
        <span id="time">15</span> seconds.
    </div>
</body>
</html>

使用 jQuery UI 微调器小部件

spinner 小部件是在 1.9 版本中添加到 jQuery UI 中的,它增强了一个带有向上和向下按钮的input元素,这样用户就可以通过一系列值来旋转。使用spinner方法应用微调控件,如清单 22-14 所示。

清单 22-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="jquery-ui-1.10.3.custom.css"/>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <style type="text/css">
        input {width: 150px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#entry").spinner();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="0" />
    </div>
</body>
</html>

在图 22-12 中可以看到input元素的变换方式,以及点击 jQuery UI 添加到元素中的按钮的效果。

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

图 22-12 。创建和使用微调器

使用带有 HTML5 输入元素类型的微调器小部件

HTML5 支持input元素的 type 属性的一些新值,其中一个与使用 spinner 小部件有相似的效果:类型number。你可以在清单 22-15 中看到我是如何使用这种类型的。

清单 22-15 。使用 HTML5 数字输入元素

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <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">
        input {width: 150px;}
    </style>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="0" type="number" />
    </div>
</body>
</html>

我从这个例子中取出了所有的 JavaScript 库和代码,以强调内置浏览器对新类型的input元素的支持。图 22-13 向你展示了谷歌浏览器如何显示这个列表。

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

图 22-13 。使用 Google Chrome 中的数字类型输入元素

这种方法比 jQuery UI 微调器有一些优势,因为更改值的控件的实现不是 HTML5 标准的一部分,这允许浏览器为用户提供特定于设备的导航。jQuery UI 微调器总是使用向上和向下按钮,这在像智能手机这样的小型触摸屏设备上很难使用。

新的number类型的最大问题是大多数浏览器忽略了它,即使是那些实现了其他 HTML5 特性的浏览器。而且很难将原生 HTML5 spinner 与 jQuery UI 混合使用,因为 spinner 小部件在调用 spinner 方法时不会检查input元素的类型。清单 22-16 显示了一个示例 HTML 文档,该文档将微调控件应用于类型为numberinput元素。

清单 22-16 。混合 jQuery UI 小部件和 HTML5 输入元素类型

<!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 type="text/css">
        input {width: 150px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#entry").spinner();
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="0" type="number" />
    </div>
</body>
</html>

我已经恢复了 JavaScript 库和代码,你可以在图 22-14 中看到效果——两组按钮来改变input元素中的值。新的input元素类型的浏览器实现和 jQuery UI 对它们的处理还不够成熟可靠,我建议避免使用它们,尤其是在组合中。

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

图 22-14 。组合 HTML5 数字输入元素和 jQuery UI 微调器

配置微调器小部件

微调器小部件支持一系列设置,允许您自定义其操作方式,如表 22-6 中所述,并在接下来的章节中演示。

表 22-6 。微调器设置

环境描述
culture指定用于分析和格式化数据值的区域设置。
disabled设置为true.时禁用微调器
icons指定用于微调按钮的图标(默认图标是上下箭头)。
incremental指定当按住其中一个按钮时,值如何递增。当设置为true时,按住按钮的时间越长,变化率将增加。当设置为false时,变化率将保持不变。您还可以指定一个函数来自定义速率变化。
max指定允许的最大值。
min指定允许的最小值。
numberFormat指定微调器显示的数字格式。
page指定页面的大小,这是当使用pageUppageDown方法时值的变化量(将在本章后面描述)。
step指定单击向上和向下按钮时值的变化量。

配置基本微调器行为

微调小部件的基本行为由四个设置控制:minmaxsteppage。在清单 22-17 中,你可以看到我是如何使用这些属性来约束微调器将支持的值以及它们是如何递增和递减的。

清单 22-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="jquery-ui-1.10.3.custom.css"/>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <style type="text/css">
        input {width: 150px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#entry").spinner({
                min: 2,
                max: 100,
                step: 2,
                page: 5
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="0" />
    </div>
</body>
</html>

minmax属性不强制验证input元素——它们只控制向上和向下按钮使用的值的范围。一旦达到了由max属性定义的限制(例如,按下向上按钮不会再增加值),用户仍然可以直接编辑input元素的内容并插入一个更大的值(或非数值)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示参见第十三章了解如何对输入元素进行验证的细节

steppage属性控制微调器小部件如何增加和减少数值。step属性指定当用户按下小部件添加的一个按钮时,值的变化量;page属性指定了当pageUppageDown方法被调用时值的变化量(我将在本章后面描述这些方法)。

在清单中,我指定了最小值 2 和最大值 100。我使用step属性告诉 jQuery UI 向上和向下按钮应该将值改变 2,使用page属性告诉 jQuery UI 通过将值增加或减少 5 来响应pageUppageDown方法。你可以在图 22-15 中看到效果。

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

图 22-15 。控制微调器小部件的基本行为

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示注意min值不会影响input元素显示的初始值。我已经将input元素上的value属性设置为零,这个值小于我在设置微调器时使用的min值。

如果用户输入一个超出允许范围的值,然后单击向上或向下按钮,微调器小部件会将input元素的内容重置为允许的最小值。你可以在图 22-16 中看到效果。

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

图 22-16 。微调器重置输入元素值

更改微调按钮图标

使用icons属性设置上下按钮显示的图标。默认图标是上下箭头,但是它们可以被设置为任何 jQuery UI 图标(我在第十八章的中描述过),如清单 22-18 所示。

清单 22-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 type="text/css">
        input {width: 150px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#entry").spinner({
                min: 2,
                max: 100,
                step: 2,
                page: 5,
                icons: {
                    up: "ui-icon-circle-plus",
                    down: "ui-icon-circle-minus",
                }
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="0" />
    </div>
</body>
</html>

用具有updown属性的对象来设置icons属性,这两个属性定义了将用于相应按钮的图标。我指定了加号和减号图标,你可以在图 22-17 中看到结果。

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

图 22-17 。更改微调器小部件使用的图标

控制变化率

incremental属性用于设置当用户按住updown按钮时值的变化率。将此属性设置为true将逐渐增加按钮被按住的时间越长,值改变的速率越大;值false保持变化率不变。第三个选择是指定一个定制变化率的函数,如清单 22-19 所示。

清单 22-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 type="text/css">
        input {width: 150px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#entry").spinner({
                incremental: function (spins) {
                    return Math.pow(spins, 2);
                }
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="0" />
    </div>
</body>
</html>

传递给该函数的参数是按钮被按住的持续时间相当于旋转的次数。该函数返回应该显示的值,我的示例返回旋转计数的平方。

设置数字格式

微调器显示的数字格式由numberFormatculture属性控制,并且依赖于一个名为 Globalize 的外部库。

您可以从https://github.com/jquery/globalize获得全球化文件。点击Releases链接,选择你想要的版本(在我写这篇文章的时候,最新的版本是0.1.1,下载一个zip或者tar.gz的档案。从归档文件中提取文件,并将以下文件复制到包含example.html和 JavaScript 库文件的文件夹中。

  • lib/globalize.js
  • lib/cultures/globalize.cultures.js

第一个文件包含用于处理本地化的 JavaScript 代码,第二个文件包含 Globalize 库附带的一组完整的语言环境。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示lib/cultures文件夹中还有其他较小的文件,用于处理单个区域设置,如果您只处理有限的区域设置,可以使用这些文件。

微调小部件的numberFormat属性指定数字的格式,而culture属性指定将使用其格式约定的区域设置。在清单 22-20 中,您可以看到两个属性都在使用。

清单 22-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"/>
    <script src="globalize.js"></script>
    <script charset="utf-8" src="globalize.cultures.js"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <style type="text/css">
        input {width: 150px;}
    </style>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#entry").spinner({
                culture: "fr-FR",
                numberFormat: "C"
            });
        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="5.00"/>
    </div>
</body>
</html>

必须在导入globalize.cultures.js文件之前导入globalize.js文件,以便可以向主库注册语言环境信息。在配置微调器时,我将culture设置为fr-FR(这是讲法语的法国的地区指示符),将numberFormat设置为C,这指定了一种货币。你可以在图 22-18 中看到结果。

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

图 22-18 。设置微调器小部件的区域性和格式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示如果省略文化设置,区域设置默认为美国的设置。

法国使用欧元作为其货币,将符号置于数字之后,并用逗号分隔数字的整数部分和小数部分。

注意,我为本地信息设置了script元素的 charset 属性,如下所示:

...
<scriptcharset="utf-8"src="globalize.cultures.js"></script>
...

您可以使用meta元素为 HTML 文档设置字符集,但是如果您还没有这样做——我在示例文档中没有这样做——那么您应该为包含地区信息的script元素显式设置字符集。如果没有这个,大多数浏览器在显示其他地区的货币符号时会有问题,如图图 22-19 所示,它应该显示欧元符号,但却被解释为无意义。

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

图 22-19 。从区域脚本元素中省略字符集属性的效果

使用微调器方法

jQuery UI 微调器小部件支持表 22-7 中描述的方法。

表 22-7 。旋转方法

方法描述
spinner("destroy")从基础元素中移除对话框小部件
spinner("disable")已禁用微调器小部件
spinner("enable")启用微调器小部件
spinner("option")获取或设置设置
spinner("pageDown", count)将微调器值减少指定的页数
spinner("pageUp", count)将微调器值增加指定的页数
spinner("stepDown", count)按照指定的步数递减微调器值
spinner("stepUp", count)按照指定的步数增加微调器值
spinner("value")获取或设置微调器的当前值

在清单 22-21 中,你可以看到我是如何将特定于 spinner 的方法应用到这个例子中的。

清单 22-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"/>
    <script src="globalize.js"></script>
    <script  src="globalize.cultures.js"></script>
    <link rel="stylesheet" type="text/css" href="styles.css"/>
    <style type="text/css">
        input {width: 150px;}
        button { margin-top: 10px; }
    </style>
    <script type="text/javascript">
        $(document).ready(function () {

            $("#entry").spinner({
                culture: "en-US",
                numberFormat: "C",
                step: 2,
                page: 10
            });

            $("button").button().click(function () {
                $("#entry").spinner(this.id);
                console.log("Value: " + $("#entry").spinner("value"));
            });

        });
    </script>
</head>
<body>
    <h1>Jacqui's Flower Shop</h1>
    <div class="ui-widget">
        Enter value: <input id="entry" value="5.00"/>
    </div>
    <div>
        <button id="pageDown">Page Down</button>
        <button id="stepDown">Step Down</button>
        <button id="stepUp">Step Up</button>
        <button id="pageUp">Page Up</button>
    </div>
</body>
</html>

我添加了button元素,用来调用微调控件上的方法,根据steppage值递增和递减值。你可以在图 22-20 中看到结果。

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

图 22-20 。以编程方式控制微调器的值

如果查看浏览器控制台,您会看到如下输出:

Value: 8
Value: 10
Value: 12

微调器value方法返回无格式值,不受culturenumberFormat设置的影响。如果您使用 jQuery 选择底层的input元素并使用val方法,您将获得格式化的值。

使用微调器事件

jQuery UI 微调器小部件支持表 22-8 中描述的事件。

表 22-8 。对话事件

事件描述
create创建小部件时触发
change当微调器的值改变并且底层的input元素失去焦点时触发
spin当值递增或递减时触发
start在值递增或递减之前触发
stop值递增或递减后触发

在清单 22-22 中,你可以看到我是如何更新前面的例子来写出微调器的值以响应stop事件的。

清单 22-22 。使用停止事件

...
<script type="text/javascript">
    $(document).ready(function () {
        $("#entry").spinner({
            culture: "en-US",
            numberFormat: "C",
            step: 2,
            page: 10,
            stop: function () {
                console.log("Value: " + $("#entry").spinner("value"));
            }
        });

        $("button").button().click(function () {
            $("#entry").spinner(this.id);
            //console.log("Value: " + $("#entry").spinner("value"));
        });

    });
</script>
...

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 提示您可以通过取消spinstart事件来停止数值的改变。jQuery 对事件的支持详见第九章。

摘要

在本章中,我向您展示了 jQuery UI 对话框和 spinner 小部件。按照与其他小部件章节相同的格式,我将重点放在对话框和微调器小部件支持的设置、方法和事件上。在第二十三章中,我向你展示了菜单和工具提示部件。

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

HTML5入门基础

2024-06-16 09:06:50

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