【译著】20章 jQuery — 《精通ASP.NET MVC 3框架》
说明1:本书的文字翻译工作已经完成,目前正处于出版社审核阶段,具体出版日期已经不是我决定的事情了。感谢园友对此书的广泛关注,这里贴出第20章内容。
说明2:本园博主牧童先生已经贴出了本章的大部分内容(参见这里),个人认为,他的翻译是很准确的。
C H A P T E R 20
■ ■ ■
jQuery
Write less, do more—that’s the core promise of jQuery, a free, open source JavaScript library first released in 2006. It has won kudos from web developers on all platforms because of the way it cuts out the pain of client-side coding. It provides an elegant CSS 3–based syntax for traversing your DOM, a fluent API for manipulating and animating DOM elements, and extremely concise wrappers for Ajax calls—all carefully abstracted to eliminate cross-browser differences.
写得少、做得多 — 这是jQuery的核心承诺,它是2006年发布的一个免费开源的JavaScript库。由于它消除了客户端编码的痛苦,已经在所有平台的web开发者中赢得了很高的声誉。jQuery提供了一个基于CSS 3的优雅语法来遍历DOM、一个流畅的API来操纵和活跃DOM元素、以及非常简练的封装程序进行Ajax调用 — 所有这些都作了精心提炼,以消除跨浏览器的差异。
Microsoft has embraced jQuery and integrated it into the MVC Framework. When we looked at unobtrusive client validation and Ajax, it was jQuery that was doing all the hard work behind the scenes.
微软已经采纳了jQuery,并将其集成到了MVC框架中。当我们查看非唐突客户端验证和Ajax效果时,其实正是jQuery在幕后辛勤劳作。
jQuery is extensible, has a rich ecosystem of free plug-ins, and encourages a coding style that retains basic functionality when JavaScript isn’t available. We won’t claim it makes all client-side coding easy, but it is usually far easier than raw JavaScript, and it works great with the MVC Framework. In this chapter, we’ll show you the basic theory of jQuery and how to use it to add some sparkle to an MVC Framework application.
jQuery是可扩展的、具有丰富的免费插件、并且鼓励在JavaScript失效时采用一种保留基本功能的编码风格。我们并非声称它能使所有客户端编码简易,但它确实比原先的JavaScript容易许多,而且它与MVC框架配合得很好。在本章中,我们将展示jQuery的基本理论,以及如何用它把一些闪光的东西添加到MVC框架的应用程序上。
In a book about the MVC Framework, there is a limit to how much detail we can provide about jQuery. If you want to go beyond the examples we provide in this chapter (and we suggest you do), then you can find a wealth of information about jQuery at www.jquery.com. We recommend the book jQuery in Action, by Bear Bibeault and Yehuda Katz, published by Manning.
在一本关于MVC框架的书中,我们不可能提供jQuery的很多细节。如果你想进入本章所提供的示例之外的领域(而且我们建议你这样做),那么你可以在www.jquery.com上找到关于jQuery的丰富信息。我们也推荐《jQuery in Action》这本书,由Bear Bibeault和Yehuda Katz所著,Manning出版。
Creating the Project
创建项目
To demonstrate the key jQuery features, we have created a simple MVC Framework application that lists mountain summits and their heights. Given that jQuery is a client-side technology, we will focus on the Razor view and HTML that this application generates. Listing 20-1 shows the view.
为了演示jQuery关键特性,我们创建了一个简单的MVC框架应用程序,它列出山峰及其高度。考虑到jQuery是一项客户端技术,因此我们将把注意力集中在Razor视图、以及应用程序所生成的HTML上。清单20-1演示了这个视图。
Listing 20-1. The Sample Application Index.cshtml View
清单20-1. 示例应用程序的Index.cshtml视图
@using MvcApp.Models; @model IEnumerable<Summit> @{ ViewBag.Title = "List of Summits"; } <h4>Summits</h4> <table> <thead> <tr><th>Name</th><th>Height</th><th></th></tr> </thead> @foreach (Summit s in Model) { <tr> <td>@s.Name</td> <td>@s.Height</td> <td> @using (Html.BeginForm("DeleteSummit", "Home")) { @Html.Hidden("name", @s.Name) <input type="submit" value="Delete" /> } </td> </tr> } </table> @Html.ActionLink("Add", "AddSummit") @using (Html.BeginForm("ResetSummits", "Home")) { <input type="submit" value="Reset" /> }
The view model for this view is a sequence of Summit objects, where the summit class has two properties: Name and Height. In the controller, we generate some example summits and pass them to the view, generating the HTML shown in Listing 20-2.
该视图的视图模型是一个Summit(山峰)对象序列,这个山峰类有两个属性:Name和Height。在控制器中,我们生成了一些简单的山峰对象,并把它们传递给视图,该视图生成的HTML如清单20-2所示。
Listing 20-2. The HTML Generated by the Sample Application
清单20-2. 示例应用程序生成的HTML
<!DOCTYPE html> <html> <head> <title>List of Summits</title> <link href="/Content/Site.css" rel="stylesheet" type="text/css" /><script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> </head> <body> <h4>Summits</h4> <table><thead><tr><th>Name</th><th>Height</th><th></th></tr> </thead> <tr><td>Everest</td> <td>8848</td> <td> <form action="/Home/DeleteSummit" method="post"> <input id="name" name="name" type="hidden" value="Everest" /> <input type="submit" value="Delete" /> </form> </td> </tr> <tr><td>Aconcagua</td><td>6962</td> <td> <form action="/Home/DeleteSummit" method="post"> <input id="name" name="name" type="hidden" value="Aconcagua" /> <input type="submit" value="Delete" /> </form> </td> </tr> ...ommitted other summit tr elements(忽略了其它山峰的tr元素)... </table> <a href="/Home/AddSummit">Add</a> <form action="/Home/ResetSummits" method="post"> <input type="submit" value="Reset" /> </form> </body> </html>
We have omitted some of the table rows for clarity. Figure 20-1 shows how this HTML is displayed by the browser. We’ve switched away from the Visual Studio built-in browser for this chapter and used Internet Explorer 9 instead.
为了清晰起见,我们省略了一些表行。图20-1演示了浏览器所显示的这个HTML。本章我们摒弃了Visual Studio内建的浏览器,而是使用Internet Explorer 9。
Figure 20-1. The sample application HTML rendered by the browser
图20-1. 浏览器渲染的示例应用程序的HTML
We know this looks pretty unpleasant, but bear with us. We’ll address some of the appearance issues as we explore the jQuery features.
我们承认,这个外观很不舒服,但请忍一忍。我们将在考察jQuery特性的过程中解决一些外观问题。
Referencing jQuery
引用jQuery
Every new MVC Framework project that Visual Studio creates includes the jQuery library files, which can be found in the /Scripts folder. There are a number of jQuery files, and it is important to know what each of them does, as described in Table 20-1.
Visual Studio创建的每一个新的MVC框架项目都会包含jQuery库文件,你可以在“/Scripts”文件夹中找到它们。这里有许多jQuery文件,但重要的是了解它们每一个是做什么的。表20-1描述了它们的作用。
Library File 库文件 |
Description 描述 |
---|---|
jquery-1.5.1.js jquery-1.5.1.min.js |
The regular and minimized versions of the core jQuery library. 核心jQuery库的常规版和最小化版。 |
jquery-ui.js jquery-ui.min.js |
The regular and minimized versions of the jQuery UI library. See the “Using jQuery UI” section of this chapter for more information. jQuery UI库的常规版和最小化版。更多信息参见本章“使用jQuery UI”小节。 |
jquery-unobtrusive-ajax.js jquery-unobtrusive-ajax.min.js |
The regular and minimized versions of the library that supports unobtrusive Ajax, described in Chapter 19. 非唐突Ajax支持库的常规版和最小化版,第19章作过描述。 |
jquery-validate.js jquery-validate.min.js |
The regular and minimized versions of the unobtrusive client-side validation feature, described in Chapter 18. 非唐突客户端验证特性的常规版和最小化版,第18章作过描述。 |
jQuery-1.5.1-vsdoc.js jQuery-validate-vsdoc.js |
IntelliSense support for the core and validation libraries. See the “Writing jQuery Code” section of this chapter for details. 对核心库和验证库的智能支持。详见本章的“编写jQuery代码”小节。 |
Two versions of each file are available: the regular and minimized versions. The regular versions are human-readable and are useful during development. When we have a problem, we can use the JavaScript debugger in our browser and see what’s going on. They are also useful for simply learning about jQuery and JavaScript in general.
每一个文件都有两个版本可供选择:常规版和最小化版。常规版有较好的可读性,在开发期间是很有用的。当遇到一个问题时,我们可以使用浏览器中的JavaScript调试器来查看正在发生的事情。对于简单学习jQuery和JavaScript,常规版通常也是有用的。
■ Tip There are also a set of files in the ~/Scripts folder whose names start with Microsoft, for example MicrosoftAjax.js. These are from version 2 of the MVC Framework and predate Microsoft fully embracing jQuery in ASP.NET MVC. We don’t discuss these files since they have been superseded and are included in MVC Framework just for compatibility with earlier versions.
提示:在~/Scripts文件夹中也有一组以Microsoft开头的文件,例如,MicrosoftAjax.js。这些文件来自MVC框架版本2,而且早期微软就在ASP.NET MVC中完全采纳了jQuery。我们不讨论这些文件,因为它们已经被取代,把它们包含在MVC框架之中只是为了与早期版本兼容。
The minimized files contain the same JavaScript code but processed to reduce the size of the files that the browser has to download. Comments, long variable names, and unnecessary whitespace are all removed. It may not sound like much, but minimized files can be significantly smaller than their regular counterparts.
最小化文件含有同样的JavaScript代码,但被作了处理,以减小浏览器下载文件的大小。注释、长变量名、和不必要的空格均被删除。这听起来不算什么,但最小化文件要比常规副本小得多。
MANAGING JQUERY VERSIONS
管理jQuery版本
As we write this, Visual Studio creates MVC Framework projects using jQuery 1.5.1. The MVC Framework is released on a different schedule than jQuery. The current version is 1.6.1, but it will almost certainly have changed again by the time you are reading this book. If you want to update the version of jQuery, simply open the Package Manager console (from the Tools → Library Package Manager menu), and enter the following command:
正如我们写到的,Visual Studio创建MVC框架项目采用的是jQuery1.5.1。MVC框架与jQuery有不同的发布计划。jQuery的当前版本是1.6.1,但在你阅读这本书时,它几乎肯定已经发生了变化。如果你想更新jQuery版本,可以简单地打开Package Manager(包管理器)控制台(“工具” → “Library Package Manager(库包管理器)”菜单),并输入以下的命令:
Update-Package jquery
This will remove your project’s existing jQuery script files and replace them with the latest versions. You will then need to update /Views/Shared/_Layout.cshtml so that it references the newly added files, for example changing the following:
这会删除项目中已有的jQuery脚本文件,并用最新版代替。然后你需要更新/Views/Shared/ _Layout.cshtml,以使它引用这些新添加的文件,例如,把下列语句:
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" ...
to this:
修改成:
<script src="@Url.Content("~/Scripts/jquery-1.6.1.min.js")" ...
We give more details on how to reference the jQuery libraries shortly.
我们很快会详细说明如何引用jQuery库。
New ASP.NET MVC 3 projects include by default a reference to the jQuery library in the default layout file, ~/Views/Shared/_Layout.cshtml, as shown in Listing 20-3.
默认情况下,新的ASP.NET MVC3项目在默认的布局文件“~/Views/Shared/ _Layout.cshtml”中包含了一个对jQuery库的引用,如清单20-3所示。
Listing 20-3. The jQuery Reference in _Layout.cshtml
清单20-3. _Layout.cshtml中的jQuery引用
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> </head> <body> @RenderBody() </body> </html>
If we want to use jQuery in a view that does not use the default layout, then we need to make sure to copy the script element to the layout that the view does use, or directly into the view itself.
如果想在一个不使用默认布局的视图中使用jQuery,则需要确保把这个script元素拷贝到该视图真正使用的布局中,或者直接拷贝到该视图之中。
■ Tip For Internet applications, it can make sense to obtain the jQuery library from a content distribution network (CDN). See the “Using a CDN for JavaScript Libraries” sidebar in Chapter 18 for details.
提示:对于Internet应用程序,从(微软的)内容分发网络(CDN)获取jQuery库可能是有意义的。详见第18章的补充说明“使用JavaScript库的CDN”。
Writing jQuery Code
编写jQuery代码
A couple of tools and techniques make learning and working with jQuery simpler. The first is IntelliSense support for Visual Studio, which adds autocompletion for jQuery functions and variables; however, unlike IntelliSense for C#, we have a little work to do in order to enable this feature.
有两个工具和技术使得学习和使用jQuery变得简单些。第一个是Visual Studio的IntelliSense(智能感应)支持,它为jQuery函数和变量添加了自动完成功能。然而,与C#的智能感应不同,为了启用这一特性,我们需要做一些工作。
In the ~/Scripts folder, you will find the file jquery-1.5.1-vsdoc.js. To enable jQuery IntelliSense, we have to add a script element that references this file to the layout or view we are working on, as shown in Listing 20-4.
在~/Scripts文件夹中,你会发现jquery-1.5.1-vsdoc.js文件。要开启jQuery的智能感应,必须把引用这个文件的script元素添加到正在使用的布局或视图,如清单20-4所示。
Listing 20-4. Adding jQuery IntelliSense Support to a Layout
清单20-4. 把jQuery智能感应支持添加到一个布局
... <head> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> @if (false) { <script src="http://www.cnblogs.com/Scripts/jquery-1.5.1-vsdoc.js" type="text/javascript"></script> } </head> ...
We don’t want the browser to actually download this file, because it contains information that is useful only to Visual Studio, so we use Razor to create an if block that always evaluates to false. This looks kind of odd—and it is, we guess—but it gives Visual Studio the information it needs to perform jQuery IntelliSense and stops our users from having to download an otherwise-unneeded file. Once we have added the script element, we can autocomplete jQuery terms just as we would when writing C#, as shown in Figure 20-2.
我们并不希望浏览器实际下载这个文件,因为它只包含了对Visual Studio有用的信息,因此,我们用Razor创建了一个总是对false进行评估的if块,这看起来有些奇怪 — 而且它确实奇怪 — 但它却给Visual Studio执行jQuery智能感应提供了信息,并阻止用户去下载一个其实不需要的文件。一旦添加了这个script元素,我们就可以像写C#一样自动完成jQuery名词,如图20-2所示。
Figure 20-2. Visual Studio IntelliSense for jQuery
图20-2. Visual Studio的jQuery智能感应
Unfortunately, we have to add the script element shown in Listing 20-4 to every view or layout in which we want jQuery IntelliSense. It isn’t enough to put the reference in a layout, for example. We must also add it to individual views, which can be a little frustrating. That said, the benefits of IntelliSense, especially when learning jQuery, can be worth the inconvenience.
不幸的是,我们必须把清单20-4所示的script元素添加到每一个我们希望使用jQuery智能感应的视图或布局。例如,把这个引用放在布局是不够的。我们还必须把它添加到个别视图,这有点让人沮丧。也就是说,只有在学习jQuery时,智能感应的这种不方便才可能是有价值的。
Creating a jQuery Sandbox
创建一个jQuery沙箱
It is perfectly possible to learn jQuery using Visual Studio. We edit a view, save the file, reload the browser, and see what effect our script has. If you are new to jQuery, one of the best ways to experiment with jQuery is to use the developer tools available your browser. This approach lets you experiment with jQuery on the fly and see immediate results. The most useful browsers in this regard are Google Chrome and Mozilla Firefox. If you are a die-hard Internet Explorer user, you can use the developer tools in IE9, but they are not as good as those in Chrome or Firefox.
完全可以用Visual Studio来学习jQuery。我们编辑一个视图、保存此文件、刷新浏览器,并查看我们的脚本有什么效果。如果你是jQuery新手,用jQuery进行实验的最好方式是使用浏览器可用的开发者工具。这个方法让你在闲暇中对jQuery进行实验,并看到即时结果。在这方面最有用的浏览器是Google Chrome和Mozilla FireFox,如果你是顽固的IE用户,你可以使用IE9中的开发者工具,但这些工具没有Chome和FireFox那么好用(可见,本小节标题中的所谓jQuery“沙箱(Sandbox)”意指:创建一个可以考察jQuery效果的环境,在这个环境中,通过输入并执行一些jQuery脚本,便可以看到jQuery的执行效果 — 译者注)。
Using Firefox
使用Firefox
One of the most popular combinations for writing JavaScript in general is Firefox with the free Firebug add-on. Firebug is an open source tool that neatly integrates into Firefox and provides an excellent set of features for HTML, CSS, and JavaScript development.
大体上,编写JavaScript最受欢迎的一种组合是Firefox与免费插件Firebug的组合。Firebug是一个开源工具,它极佳地集成到了Firefox之中,并为HTML、CSS、以及JavaScript开发提供了一组出色的特性。
Of particular importance to us is the JavaScript command line, with which we can type and execute JavaScript code on the fly and see the effect it has on the web page immediately. This may not sounds like much, but this is a huge help when trying to get to grips with jQuery.
对我们而言,特别重要的是JavaScript命令行,我们可以用它在闲暇时键入和执行一些Javascript代码,并及时看到它在web页面上所具有的效果。也许这听起来不算什么,但在试图要真正掌握jQuery时,这是一种巨大的帮助。
If you are a Firefox user, install Firebug (available from http://getfirebug.com), and load the HTML page you want to experiment with. This can be any page at all, including, of course, a page generated by an MVC Framework application. When the page is loaded, click the Firebug button at the top of the browser window, as shown in Figure 20-3.
如果你是一个Firefox用户,可安装Firebug(可从http://getfirebug.com下载),并载入你想进行实验的HTML页面。可以是任意页面,当然也包括由MVC框架应用程序生成的页面。当页面载入后,点击浏览器窗口顶部的Firebug按钮,如图20-3所示。
Figure 20-3. Using Firebug in the Firefox browser
图20-3. 在Firefox浏览器中使用Firebug
Switch to the Console tab and, if required, click the Enable link to switch on the command-line feature. If we are working with a web page that already loads the jQuery library, then we can just type jQuery statements into the console and see their effect immediately. If we are working with a page that doesn’t include jQuery, then we need to type the JavaScript statements shown in Listing 20-5 (as a single line).
切换到Console(控制台)选项卡,如果必要,点击Enable(启用)链接,以打开命令行特性。如果我们正在处理一个已经加载了jQuery库的web页面,那么,只要把jQuery命令键入到控制台,就可以立即看到它们的效果。如果正在处理的页面并未包含jQuery,那么,就需要键入如清单20-5所示的JavaScript语句(作为一个单行)(注意,不管你键入的代码事实上是几条语句,都以一个单一的行输入,如清单20-5中有三条语句,但在命令行窗口中是作为一行输入的 — 译者注)。
Listing 20-5. Loading jQuery into a Web Page
清单20-5. 把jQuery载入Web页面
var s=document.createElement('script'); s.setAttribute('src', 'http://jquery.com/src/jquery-latest.js'); document.getElementsByTagName('body')[0].appendChild(s);
These statements create a new script element that references the jQuery library.
这些语句创建了一个引用jQuery库的script元素。
■ Tip You can save these statements as a bookmarklet or get one ready-made from www.learningjquery.com/2006/12/jquerify-bookmarklet.
提示:你可以把这些语句保存为一个书签小程序(Bookmarklet,字典中没有此单词,它类似于Java语言的Javalet、Servlet(Java、服务器端Java小程序),故这里将此单词译为书签小程序 — 译者注),或从www.learningjquery.com/2006/12/jquerify-bookmarklet得到一个现成的。
The URL from which the jQuery library is obtained is shown in bold. We have taken the latest version of the library from the http://jquery.com web site, but you can change the URL to point to the Microsoft CDN or to the jQuery file contained within your MVC Framework project.
获取jQuery库的URL以粗体表示。我们从http://jquery.com网站获取的是jQuery库最新版,但你可以更改这个URL,以指向微软的CDN,或指向包含在你MVC框架项目中的jQuery文件。
Once we are set up, we can enter jQuery statements (or any other JavaScript statements, for that matter) into the console and see their effect immediately. In the figure, we have loaded the Microsoft home page, imported jQuery, and entered the statement jQuery('a').hide(). We’ll explain the basics of jQuery syntax later, but as soon as we press the Enter key, jQuery will find all the a elements in the web page and hide them, as shown in Figure 20-4.
一旦我们设置好了,便可以把jQuery语句(或针对同一问题的任意其它Javascript语句)输入到控制台中,并立即看到它们的效果。在上图中,我们载入了微软的主页、引入了jQuery、并输入了语句jQuery('a').hide()。我们稍后会解释基本的jQuery语法,但只要我们按Enter键,jQuery就会立即找出该web页面的所有a元素,并隐藏它们,如图20-4所示。
Figure 20-4. Hiding the a elements in the Microsoft web page
图20-4. 在微软的web页面中隐藏a元素
Hiding the anchor elements is a trivial example, but it shows how we can use Firefox and Firebug to create a sandbox for playing around with jQuery.
隐藏锚点元素只是一个微不足道的例子,但它演示了如何使用FireFox和Firebug来创建一个演示jQuery的沙箱(意指练习jQuery的环境 — 译者注)。
Using Chrome
使用Chrome
If you are a Chrome user, as we both are, then you don’t need an add-on like Firebug. The built-in developer tools are pretty good and include a JavaScript console. There is a version of Firebug—called Firebug Lite—that adds many of the Firebug features that are available in the Firefox version, but using this is strictly optional.
如果你是一个Chrome用户,就像我们俩(作者)一样,那么你不需要Firebug这样的插件。内建的开发者工具就非常好,而且也包含了一个JavaScript控制台。Firebug有一个版本 — 叫做Firebug Lite(这是Firebug的一个轻装版,是Firebug的一个子集,可用于大多数主流浏览器,当然也包括Chrome。这里的含义是可以在Chrome中使用这个Firebug Lite — 译者注) — 它添加了许多在Firefox版本中可用的许多Firebug特性,但使用它是完全随意的(因为Chrome中有内建的开发者工具 — 译者注)。
Once you have loaded a web page in Chrome, click the Customize and Control Google Chrome button (the one with the spanner icon), and select Tools → JavaScript Console. Or as a shortcut, just press Ctrl+Shift+J on any web page. Figure 20-5 shows the result.
一旦在Chrome中载入了一个web页面,点击Customize and Control Google Chrome(定制与控制Google Chrome)按钮(一个扳手形图标),并选择Tools(工具) → JavaScript Console(JavaScript控制台),或使用快捷键,只要在web页面上按Ctrl+Shift+J组合键。图20-5显示了结果。
Figure 20-5. Using the Chrome JavaScript console
图20-5. 使用Chrome JavaScript控制台
We can then enter jQuery statements into the console and see their effects immediately. If we want to experiment with web pages that do not use jQuery, then we must import the library using the statements shown in Listing 20-5.
然后我们可以把jQuery语句输入控制台,并立即看到它们的效果。如果想对未使用jQuery的web页面进行实验,那么必须用清单20-5所示的语句来引入jQuery库。
Basic jQuery Theory
基本的jQuery理论
At the heart of jQuery is a powerful JavaScript function called jQuery (). We use it to query our HTML page’s document object model (DOM) for all elements that match a CSS selector. As a simple example, jQuery("DIV.MyClass") finds all the div elements in our DOM that have the CSS class MyClass.
jQuery的核心是一个叫做jQuery()的功能强大的函数。我们用它查询HTML页面的文档对象模型(DOM),找出与一个CSS选择器匹配的所有元素。作为一个简单的例子,jQuery("DIV.MyClass")会在DOM中找出CSS的class为MyClass的所有div元素(所谓“CSS的class”是指,HTML元素上的class标签属性,CSS可以通过这个class标签属性的值来设置这些元素在页面中的显示样式 — 译者注)。
jQuery () returns a jQuery-wrapped set: an instance of a jQuery object that lists the results and has many extra methods you can call to operate on those results. Most of the jQuery API consists of such methods on wrapped sets. For example, jQuery("DIV.MyClass").hide() makes all the matching div elements suddenly vanish. For brevity, jQuery provides a shorthand syntax, $(), which is exactly the same as calling jQuery(). Table 20-2 contains some further examples.
jQuery()返回一个jQuery的封装集:一个jQuery对象的实例,它列出了返回结果,并有许多附加方法,你可以调用这些方法对结果进行操作。大多数的jQuery API都是由封装集上的这种方法组成的。例如,jQuery("DIV.MyClass").hide()会使所有匹配的div元素突然消失。为简化起见,jQuery提供了一种简写语法,$(),它与调用jQuery()完全相同。表20-2包含了一些进一步的示例。
Example 示例 |
Description 描述 |
---|---|
$("P SPAN").addClass("SuperBig") | Adds a CSS class called SuperBig to all <span> nodes that are contained inside a <p> node 对包含在<p>节点中的所有<span>节点,添加一个值为SuperBig的CSS的class |
$(".SuperBig").removeClass("SuperBig") | Removes the CSS class called SuperBig from all nodes that have it 从包含CSS的class为SuperBig的所有节点中删除这个class。 |
$("#options").toggle() | Toggles the visibility of the element with ID options (if the element is visible, it will be hidden; if it’s already hidden, it will be shown) 切换ID为options的元素的可见性(如果该元素可见,隐藏它。如果已经隐藏,显示它) |
$("DIV:has(INPUT[type='checkbox']:disabled)").prepend("<i>Hey!</i>") | Inserts the HTML markup <i>Hey!</i> at the top of all div elements that contain a disabled checkbox 在含有禁用复选框的所有div元素的顶部插入HTML标记<i>Hey!</i>。 |
$("#options A").css("color","red").fadeOut() | Finds any hyperlink tags (i.e., <a> tags) contained within the element with ID options, sets their text color to red, and fades them out of view by slowly adjusting their opacity to zero 找出ID为options的所有超链接标签(即,<a>标签),将它们的文本颜色设置为红色,通过把它们的不透明度缓慢调节到零的方式淡出视图。 |
jQuery is extremely concise, and achieving the same effects as those produced by the examples in the table would take many lines of JavaScript. We picked the examples in the table to illustrate some of the key jQuery features, which we describe briefly in the following sections.
jQuery极其简练,而取得上表例子所产生的同样效果会需要很多行JavaScript代码。我们在上表中挑选了一些示例,以说明jQuery的一些关键特性,在接下来的几小节中我们主要描述这些特性。
Understanding jQuery Selectors
理解jQuery选择器
One concept key to understanding jQuery is selectors. One kind of selector is the strings that we pass to the jQuery function to specify the set of elements that we want to operate on. Listing 20-6 highlights the selector in a jQuery statement.
理解jQuery的关键概念是选择器。一种选择器是我们传递给jQuery函数的字符串,以指定一组要对之进行操作的元素。清单20-6高亮了jQuery语句中的选择器。
Listing 20-6. A jQuery Selector
清单20-6. 一个jQuery选择器
$("th").toggle()
The selector in this example is th, which selects all the th elements in the document. We then apply the toggle method to the selected elements. As we described in Table 20-2, the toggle method changes the visibility of elements. If we applied this jQuery statement to the HTML generated by our example project, the table headers will be hidden (and if we apply it again, they will reappear). The example in Listing 20-6 demonstrates one of the four basic selectors, which are described in Table 20-3.
此例中的选择器是th,它选择了文档中的所有th元素。然后我们把toggle(切换)方法运用于这些选中元素。正如表20-2所描述的那样,toggle方法会改变元素的可见性。如果把这个jQuery语句运用于示例项目所生成的HTML,将会隐藏表头(再次运用,又会重新出现)。清单20-6示例演示了四种基本选择器的一种,这些基本选择器如表20-3所述。
Selector 选择器 |
Description 描述 |
---|---|
$('*') | Selects all the elements in the document 选择文档中的所有元素 |
$('.myclass') | Selects all the elements to which the CSS class myclass has been assigned 选择CSS的class值为myclass的所有元素 |
$('element') | Selects all the elements of the type element 选择<element>类型的所有元素(其含义是指这个element为<元素名>,如$('p'),其中p为文档中的<p>元素,这条语句的作用是选择所有段落元素 — 译者注) |
$('#myid') | Selects the element with the ID of myid 选择ID为myid的元素 |
jQuery selectors are greedy, meaning they select as many elements as they can in the HTML DOM. One exception to this is the $('#id') selector, which selects the element with the specified ID; element IDs are expected to be unique. We can narrow our selections by providing a selection context, like this:
jQuery选择器很贪婪,意即,他们会在HTML DOM中选择尽可能多的元素。一个例外是$('#id')选择器,它只选择带有指定ID的元素,在一个文档中,各元素的ID要求是唯一的。我们可以通过提供一个选择上下文来缩小选择范围,像这样:
$('td', myElement)
which will match td elements that are descendants of myElement. You can see a selection context in use in Listing 20-17.
它将匹配myElement子节点中的td元素。你可以在清单20-17中看到选择上下文的用法。
A QUICK NOTE ABOUT ELEMENT IDS
元素id的简要说明
If you’re using jQuery, or in fact writing any JavaScript code to work with your MVC Framework application, you ought to be aware of how the HTML helpers render ID attributes. If we call the text box helper as follows, for example:
如果你正在使用jQuery,或实际编写运用于MVC框架应用程序的JavaScript代码,你应该知道HTML辅助器是如何渲染ID标签属性的。例如,如果像下面这样调用文本框辅助器:
@Html.TextBox("pledge.Amount")
it will render the following:
它将渲染如下标记:
<input id="pledge_Amount" name="pledge.Amount" type="text" value="" />
Notice that the element name is pledge.Amount (with a dot), but its ID is pledge_Amount (with an underscore). When rendering element IDs, the built-in helper methods replace dot characters with underscores. This makes it possible to reference the elements using a jQuery selector such as $("#pledge_Amount"). Note that it wouldn’t be valid to write $("#pledge.Amount"), because in jQuery (and in CSS) that would mean an element with ID pledge and CSS class Amount.
注意,该元素的name是pledge.Amount(带有一个点),但它的ID是pledge_Amount(带有一个下划线)。在渲染元素的ID时,内建的辅助器方法会用下划线替换点字符。这使得能够用诸如$("#pledge_Amount")之类的jQuery选择器来引用这个元素。需要注意的是,写成$("#pledge.Amount")是无效的,因为在jQuery中(及CSS中),这意指ID为pledge和CSS的class为Amount的元素。
We can combine the results of multiple selectors by separating each term with a comma, as shown in Listing 20-7.
通过逗号分隔各项,我们可以组合多个选择器的结果,如清单20-7所示。
Listing 20-7. Combining Selections
清单20-7. 组合选择
$('td, th')
This statement selects all the td and th elements in the DOM. We can apply selections sequentially by separating the terms with spaces, as shown in Listing 20-8.
这条语句选中了DOM中的所有td和th元素。通过用空格分隔各项,我们可以依序运用选择,如清单20-8所示。
Listing 20-8. Applying Multiple Selections Sequentially
清单20-8. 依序运用多个选择
$('td input')
In this case, we have selected all the input elements contained within td elements. In the case of our example project, this means we select the Delete buttons that are at the end of each table row but not the Reset button at the bottom of the page.
在这个例子中,选择的是包含在td元素中的所有input元素。在我们的示例项目中(指本章前面的示例 — 译者注),这意味着选择了每个表行最后的Delete按钮,但页面底部的Reset按钮不在其内。
Using Attribute Selectors
使用属性选择器
In addition to the basic selectors, there are also attribute selectors. As their name suggests, these selectors operate on attributes and their values. Table 20-4 describes the attribute selectors.
除基本选择器以外,还有属性选择器(注,这里的属性是指HTML元素(或DOM元素)的标签属性,如果要与本书前面几章的说法对应,这里应当叫做标签属性选择器,但由于本章的注意力集中于视图,把标签属性直接说成属性不会产生歧义,也为了与流行说法一致,故这里译成属性选择器 — 译者注)。顾名思义,这些选择器是针对属性及其值进行操作的。表20-4描述了这些属性选择器。
Selector 选择器 |
Description 描述 |
---|---|
$('[attr]') | Selects elements that have an attribute called attr, irrespective of the attribute value 选择有attr属性的元素,不考虑属性值 |
$('[attr]="val"') | Selects elements that have an attr attribute whose value is val 选择有attr属性且其值为val的元素 |
$('[attr]!="val"') | Selects elements that have an attr attribute whose value is not val 选择有attr属性且其值不为val的元素 |
$('[attr]^="val"') | Selects elements that have an attr attribute whose value starts with val 选择有attr属性且其值以val开头的元素 |
$('[attr]~="val"') | Selects elements that have an attr attribute whose value contains val 选择有attr属性且其值包含val的元素 |
$('[attr]$="val"') | Selects elements that have an attr attribute whose value ends with val 选择有attr属性且其值以val结尾的元素 |
$('[attr]|="val"') | Selects elements that have an attr attribute whose value is val or starts with val followed by a hyphen (val-) 选择有attr属性且其值为val、或以val开头、或val后跟连接符(val-)的元素 |
We can apply multiple attribute selectors together, in which case we select only those elements that match all of the conditions. Listing 20-9 contains an example.
也可以多个属性选择器一起运用,在这种情况下,只选择与所有条件匹配的那些元素。清单20-9包含了一个示例。
Listing 20-9. Combining Attribute Selectors
清单20-9. 组合属性选择器
$('[type][value="Delete"]')
The selects in this statement match those elements that have a type attribute (with any value) and a value attribute whose value is Delete. In the case of our example application’s HTML, this matches the Delete buttons at the end of each table row.
这条语句将选中有type属性(不管什么值)且value属性的值为Delete的那些元素匹配。在我们的示例应用程序的HTML中,它与各个表行最后的Delete按钮匹配。
Using jQuery Filters
使用jQuery过滤器
In addition to selectors, jQuery also supports filters, which are a convenient means for narrowing the range of elements that we select. Listing 20-10 shows an example of one of the basic filters.
除选择器以外,jQuery也支持过滤器,它们是缩小元素选择范围的一种便利手段。清单20-10显示了一个基本过滤器示例。
Listing 20-10. Using a Basic Filter
清单20-10. 使用一个基本过滤器
$('td:eq(8)')
The filter in this example is :eq(8), which selects only the ninth item in the array of elements matched by the selector (because these filters are zero-based). Table 20-5 describes the basic filters.
这个示例的过滤器为:eq(8),它只选择与选择器匹配的元素数组中的第九项(因为这些过滤器都是基于零的)。表20-5描述了这些基本过滤器。
Filter 过滤器 |
Description 描述 |
---|---|
:eq(n) | Selects the n-1th item in the selection 选择所选内容的第n-1项(注:这一说法与上例矛盾,按上例的说法,这里的n应当是结果数组的索引号,故应当是第n+1项。如果这里的n是指第n项,则所选元素的索引号为n-1,但不是第n-1项 — 译者注) |
:even :odd |
Selects the even-numbered or odd-numbered elements 选择偶数、或奇数元素 |
:first :last |
Selects the first or last element 选择第一、或最后一个元素 |
:gt(n) :lt(n) |
Selects all the elements whose index is greater or less than n 选择索引号大于、或小于n的元素 |
:header | Selects all elements that are headers (h1, h2, and so on) 选择所有标题元素(h1、h2等等) |
:not(selector) | Selects all the elements that do not match the selector 选择所有与选择器不匹配的元素 |
The filters can be used in conjunction with selectors, as shown in Listing 20-10, or on their own, as demonstrated in Listing 20-11.
过滤器可以和选择器联合,如清单20-10中所示。也可以单独使用,如清单20-11所示。
Listing 20-11. Using a Filter Without a Selector
清单20-11. 单独使用过滤器
$(':header')
In this example, we have used the :header filter to select all the headers. When we do this, the universal selector (*) is implied. We could have achieved the same result by using a selector that combined all the header element types ($('h1 h2 h3')), but using the filter is simpler and easier. We can combine multiple filters by appending them together, as shown in Listing 20-12.
在这个示例中,我们使用了:header过滤器来选择所有标题元素(<h1>、<h2>等 — 译者注)。当我们这么做时,隐含运用了一个通配符选择器(*)。我们也可以通过一个组合了所有标题元素类型的选择器($('h1 h2 h3'))来取得同样的结果,但使用过滤器要更简单、容易。通过把多个过滤器追加在一起,我们可以组合多个过滤器,如清单20-12所示。
■ 注:根据这一解释可知,过滤器实际上总是针对由选择器选中的对象进行过滤的,请读者务必记住这一点。如果过滤器不以选中对象为其过滤基础,过滤器就成为无源之水了 — 译者注
Listing 20-12. Applying Multiple Filters
清单20-12. 应用多个过滤器
$('td:odd:eq(1)')
This selects the td element, filters them so that only the odd-numbered items remain, and then selects the second element.
它选择td元素、对其进行过滤只保留奇数项,然后选择第二项元素。
Using Content Filters
使用内容过滤器
The next filters we will look at are content filters, which are described in Table 20-6. These filters are focused on the content of an element, both in terms of text and other elements.
我们考察的下一个过滤器是内容过滤器,描述于表20-6。这些过滤器关注于元素的内容,既关注内容的文本方面,也关注内容中的其它元素。
Filter 过滤器 |
Description 描述 |
---|---|
:contains('text') | Selects elements that contain text or whose children contain text 选择含有text、或其子元素含有text的元素 |
:has('selector') | Selects elements that have at least one child element that matches selector 选择至少有一个子元素与selector匹配的元素 |
:empty | Selects elements that have no child elements 选择没有子元素的元素 |
:parent | Selects elements that have at least one other element 选择至少有一个其他元素的元素(用中文这样说明可能更恰切些:在选择器选中的元素中挑出本身是父元素的那些元素 — 译者注) |
:first-child | Selects elements that are the first child of their parent 选择它们父节点的第一个子元素(挑出本身是第一个子节点的元素。例如,$(td:first-child),选择器选出的是所有td元素(单元格),过滤器从中挑出充当第一个子节点的那些td,结果是第一列单元格 — 译者注) |
:last-child | Selects elements that are the last child of their parents 选择它们父节点的最后一个子元素(挑出本身是最后一个子节点的元素 — 译者注) |
:nth-child(n) | Selects elements that are the nth child of their parent 选择它们父元素下的第n个子元素(挑出本身是第n个子节点的元素 — 译者注) |
:only-child | Selects elements that are the only child of their parent 仅选择它们父节点的唯一子元素(挑出本身是唯一子节点的元素 — 译者注) |
A little caution is required when using the :contains filter because it matches elements that contain the specified text and elements whose children contain it. This means that if we use the filter on its own against the HTML generated by our example application, like this:
需要稍加注意的是使用:contains过滤器的时候,因为它匹配的是含有指定文本的元素以及子元素含有此文本的元素。这意味着,如果我们针对示例应用程序生成的HTML(参见清单20-2以及图20-1 — 译者注)单独使用这个过滤器,像这样:
$(':contains("K2")')
then we select six elements: the td element that contains the text and all of this element’s parents (tr, tbody, table, body, and html elements).
那么,我们选择了六个元素:含有此文本的td元素,以及此元素的所有父元素(tr、tbody、table、body、和html元素)(但是,如果用$('tr:contains("K2")'),则挑出的只是最后一个tr,因为这一行中有一个td含有K2文本 — 译者注)。
■ Caution To preserve compatibility with CSS conventions, the nth-child filter is one-based. In other words, if you want to select elements that are the first child of their parent, use :nth-child(1) and not :nth-child(0).
小心:为了与CSS约定保持兼容,nth-child过滤器是基于一的(索引号从1开始 — 译者注)。换句话说,如果你想选择的是它们父元素的第一个子元素,须使用:nth-child(1),而不是:nth-child(0)。
Using Form Filters
使用表单过滤器
The final filters we will describe are the form filters, which are convenient for selecting elements related to HTML forms. Table 20-7 describes these elements.
我们要描述的最后一种过滤器是表单过滤器,它们对于选择与HTML表单相关的元素是方便的。表20-7描述了这些过滤器。
Filter 过滤器 |
Description 描述 |
---|---|
:button | Selects button elements and input elements whose type is button 选择按钮元素,以及其type为button的input元素 |
:checkbox | Selects checkboxes 选择复选框 |
:checked | Selects checkboxes and radio button elements that are checked 选择被选中的复选框和单选按钮元素 |
:disabled :enabled |
Selects items that are enabled or disabled, respectively 分别用于选择启用或禁用的项 |
:input | Selects input elements 选择input元素 |
:password | Selects password elements 选择口令元素 |
:radio | Selects radio buttons 选择单选按钮 |
:reset | Selects input elements whose type is reset 选择其type为reset的input元素(重置按钮) |
:selected | Selects option elements that are selected 选择被选中的option元素(选项元素) |
:submit | Selects input elements whose type is submit 选择其type为submit的input元素(递交按钮) |
:text | Selects input elements whose type is text 选择其type为text的input元素(文本框) |
Understanding jQuery Methods
理解jQuery方法
Selectors and filters let us tell jQuery which elements we want to work with. Methods are how we tell jQuery what to do. We have shown a few jQuery methods so far, such as toggle, but jQuery is a very capable library, and many methods are available. In the sections that follow, we’ll show you some of the most useful methods and demonstrate their effect. For further details and a complete list of the methods that jQuery supports, see http://jquery.com.
选择器和过滤器意在告诉jQuery,我们想处理的是哪些元素。方法则是告诉jQuery去做什么。至目前为止,我们已经演示了几个jQuery方法,如toggle等。但是jQuery是一个能力很强的库,它提供了许多可用的方法。在以下几小节中,我们将介绍一些最有用的方法,并演示其效果。对于jQuery所支持的方法的完整列表和详细信息,请参阅 http://jquery.com。
Waiting for the DOM
等待DOM
We showed you the selectors and filters in isolation because a selector or filter on its own does nothing. Now that we are ready to combine our selections with methods, we can start to add jQuery scripts to our MVC Framework application’s view. Listing 20-13 shows the skeletal view into which we will add our jQuery statements.
我们演示选择器和过滤器是孤立开来的,因为单独使用选择器和过滤器并不做任何事情。现在,我们已经做好了选择器与方法相结合的准备,可以开始把jQuery脚本添加到MVC应用程序的视图了。清单20-13显示了我们将在其中添加jQuery语句的视图骨架。
Listing 20-13. The Skeletal View
清单20-13.Skeletal视图
@using MvcApp.Models; @model IEnumerable<Summit> @{ ViewBag.Title = "List of Summits"; } @if (false) { <script src="http://www.cnblogs.com/Scripts/jquery-1.5.1-vsdoc.js" type="text/javascript"></script> } <script type="text/javascript"> $(document).ready(function () { // our jQuery code will go here // jQuery代码将放在这儿 }); </script> <h4>Summits</h4> <table> <thead> <tr><th>Name</th><th>Height</th></tr> </thead> @foreach (Summit s in Model) { <tr> <td>@s.Name</td> <td>@s.Height</td> <td> @using (Html.BeginForm("DeleteSummit", "Home")) { @Html.Hidden("name", @s.Name) <input type="submit" value="Delete" /> } </td> </tr> } </table> @Html.ActionLink("Add", "AddSummit") @using (Html.BeginForm("ResetSummits", "Home")) { <input type="submit" value="Reset" /> }
We have added our script element to the view itself, which means the scripts that we add will take effect only when this view is rendered. If we want scripts that are performed for multiple views, then we can add them to a layout.
我们对这个视图添加了script元素,这意味着,我们添加的这些脚本只有在渲染该视图时才会生效。如果希望脚本能被多个视图执行,那么可以把它们添加到布局。
■ Tip We don’t need to reference the jQuery library file in our view because it is referenced in the layout instead, as shown in Listing 20-3. We have, however, added a reference to the vsdoc file so that we benefit from IntelliSense for jQuery.
提示:我们不需要在视图中引用jQuery库文件,因为它在布局中被引用了,如清单20-3所示。我们也添加了对vsdoc文件的引用,因此,我们能够获益于jQuery的智能感应。
We have added the $(document).ready() function to our script element. This is a useful feature that means our jQuery code won’t be executed until after the DOM is loaded but before any media (including images) are available. This is a matter of timing. We don’t want our code to be executed too soon, because not all of the elements that we want to work with will be known to the browser. We don’t want to wait for the media to load, because this can take a while, and the user may have already started interacting with the page. We will use the $(document).ready() function in all the examples in this chapter.
我们把$(document).ready()函数加到了script元素。这是一个有用的特性,它意味着,在DOM加载之后,但在媒体(包括图像)可用之前,才会执行我们的jQuery代码。这是一个时间安排的问题。我们不希望代码执行过早,因为浏览器尚未知道我们要处理的全部元素。我们不想等待媒体加载,因为这可能需要一些时间,而且用户可能已经开始与页面进行交互了。在本章的所有示例中,我们都会使用$(document).ready()这个函数。
Using jQuery CSS Methods
使用jQuery的CSS方法
The best place to start applying jQuery in our example application is in the area of CSS. Using the jQuery CSS-related methods, we can significantly improve the appearance of our content. Listing 20-14 shows an example of combining jQuery selectors and CSS methods to our HTML table.
在我们应用程序示例中,开始运用jQuery最好的地方是在CSS方面。使用jQuery的CSS相关方法,我们可以明显改善内容的外观。清单20-14演示一个对HTML表格组合了jQuery选择器和CSS方法的示例。
Listing 20-14. Using Some of the jQuery CSS Methods
清单20-14.使用一些jQuery的CSS方法
@using MvcApp.Models; @model IEnumerable<Summit> @{ ViewBag.Title = "List of Summits"; } @if (false) { <script src="http://www.cnblogs.com/Scripts/jquery-1.5.1-vsdoc.js" type="text/javascript"></script> } <script type="text/javascript"> $(document).ready(function () { $('table').addClass('summitTable'); $('tr:even').css('background-color', 'silver'); $(':submit[value="Reset"], a:contains("Add")') .css('float', 'left') .css('margin', '5px'); }); </script> <h4>Summits</h4> <table> <thead> <tr><th>Name</th><th>Height</th><th/></tr> </thead> @foreach (Summit s in Model) { <tr> <td>@s.Name</td> <td>@s.Height</td> <td> @using (Html.BeginForm("DeleteSummit", "Home")) { @Html.Hidden("name", @s.Name) <input type="submit" value="Delete" /> } </td> </tr> } </table> @Html.ActionLink("Add", "AddSummit") @using (Html.BeginForm("ResetSummits", "Home")) { <input type="submit" value="Reset" /> }
This is the last time that we’ll show the entire view. From now on, we’ll just list the jQuery script, since the rest of the view won’t change from example to example.
这是我们最后一次展示视图的全部代码,此后,我们将只列出jQuery脚本,因为此后的一个个例子中,不会修改视图的其余部分。
The listing contains three CSS-related operations. The first is as follows:
上述清单含有三个CSS相关的操作。第一个如下:
$('table').addClass('summitTable');
The addClass method adds a CSS class to the selected elements, in this case, the table element. We defined the summitTable class in the Site.css file, which is referenced in the layout, as follows:
addClass方法对所选择的元素添加一个CSS的class,在此例中是table元素。我们在Site.css文件中定义了这个summitTable的class样式,Site.css文件是在布局中引用的,该样式的定义如下:
.summitTable { border: thin solid black; margin: 5px; }
The addClass method doesn’t check to see that the summitTable class exists; it just manipulates the element so that the class attribute is added, like this:
addClass方法不会检查summitTable这种class是否存在,它只会对元素进行操作,以使class属性得到添加,像这样:
<table class="summitTable">
The next statement performs what is known as zebra-striping. This is a popular effect that increases the readability of grids:
下一条语句执行一种叫做斑马条纹化(zebra-striping)的工作,这是一种提高网格可读性的流行效果:
$('tr:even').css('background-color', 'silver');
The css method modifies the style attribute of the selected elements to set the value (silver) for a specified style property (background-color). The selector in this statement selects the even-numbered tr elements. Zero is an even number in zero-based counting systems, which means that the table rows with indexes 0, 2, 4, 6, and so on, are modified as follows:
该css方法修改被选元素的style属性,以对指定的样式属性(background-color,背景色)设置一个值(silver,银色)。这条语句中的选择器选择了偶数tr元素。在以零为基的计数系统中,零是偶数,这意味着索引号为0、2、4、6等的表行会被修改成如下形式:
<tr style="background-color: silver; ">
USING JQUERY METHOD OVERLOADS
使用jQuery方法重载
Many jQuery methods have several overloaded versions that take different numbers of arguments. For example, when the css method is used with one argument, like this:
很多jQuery方法都有几个重载版本,它们具有不同数目的参数。例如,当以一个参数使用css方法时,像这样:
$('tr:first').css('background-color')
then the method just returns the current value of the specified style element, in this case, the background-color value. This value can then be used as an argument to other methods, like this:
那么,该方法只返回该元素指定样式的当前值,在这个例子中,是backgroud-color的值。这个值然后可以被用作其他方法的参数,像这样:
$('tr').css('background-color', $('tr:first').css('background-color'))
which sets the background-color for all tr elements to match that of the first tr element.
这会对所有tr元素都设置与第一个tr元素匹配的background-color(背景色,此句的作用是将所有表行的背景色都设置成与第一行匹配的背景色 — 译者注)。
The final statement demonstrates that we can chain jQuery methods together, as follows:
最后一条语句演示的是我们可以把jQuery方法链接在一起,如下所示:
$(':submit[value="Reset"], a:contains("Add")') .css('float', 'left') .css('margin', '5px');
The selector in this example matches the two elements at the bottom of the page: the Add link and the Reset button. We set a value for two different styles by applying the css method to the results generated by a previous call to the css method. Method chaining is one of the key characteristics of a fluent API, which can make coding simpler and code easier to read. Most of the jQuery methods return a collection of jQuery elements on which further methods can be called. Our example showed only two CSS-related methods. Table 20-8 describes the most useful CSS-related methods that jQuery supports.
此例中的选择器与页面底部的两个元素匹配:Add链接和Reset按钮。通过对前一个css方法调用所生成的结果运用css方法,我们设置了两个不同样式的值。方法链接是流畅API的关键特征之一,它使编码变得更简单易读。大部分jQuery方法都返回一个jQuery元素集合,后继方法可以对之进一步调用。我们的示例只演示了两个CSS相关方法。表20-8描述了jQuery支持的最有用的CSS相关方法。
Method 方法 |
Description 描述 |
---|---|
addClass('myClass') | Adds the specified class name to the class attribute of selected elements 将指定的class名添加到选中元素的class属性(应当是指定的class值,形成的结果应当是:<… class="myClass" …> — 译者注) |
hasClass('myClass') | Returns true if the any of the selected elements have been assigned the specified class 如果选中元素具有指定的class,返回true |
removeClass('myClass') | Removes the specified class name from the class attribute of selected elements 从选中元素的class属性中删除指定的class名(删除值为myClass的class属性 — 译者注) |
toggleClass('myClass') | Adds the specified class if it isn’t present and removes it otherwise 如果指定的class不存在,则添加;否则,删除它 |
css('property', 'value') | Adds the specified property and value to the style attribute of selected elements 将指定的属性(property)和值(value)添加到选中元素的style属性 |
Although it can be useful to manipulate CSS when the DOC loads, these methods are often combined with jQuery events to change the appearance of HTML elements in response to an event occurring; see the “Using jQuery Events” section later in this chapter for more details of how jQuery handles events. Figure 20-6 shows the effect of the CSS changes performed by the script in Listing 20-14.
尽管DOC加载时这些方法对操作CSS是有用的,但它们通常是与jQuery事件进行组合,在响应事件发生时改变HTML元素的外观。详见本章后面部分的“使用jQuery事件”小节。图20-6显示了执行清单20-14脚本的CSS变化效果。
Figure 20-6. Using jQuery to manipulate CSS
图 20-6. 使用jQuery操纵CSS
■ Tip In addition to these methods, there are others that can be used to read or write elements’ style properties directly, including height(), width(), and position(). See the jQuery API reference for further details.
提示:除了这些方法以外,还有一些其它方法可用于直接读写元素的style属性,包括 height()、width()、以及position()等。更详细的信息参见jQuery API参考。
Working with the DOM
使用DOM
jQuery’s support for manipulating the DOM is so comprehensive that we can only just scratch the surface in this book. We can add, remove, and change DOM elements, and we can even move elements from one part of the DOM to another. In this section, we’ll provide some basic examples, but a full appreciation of the jQuery DOM capabilities requires diligent perusal of the API reference and some careful experimentation. Listing 20-15 demonstrates creating new elements in the DOM and using jQuery to add a new column to the table to express the heights of the summits in feet.
jQuery对操作DOM的支持是非常全面的,本书我们只能作粗浅介绍。我们可以添加、删除和修改DOM元素,甚至可以把元素从DOM的一个部分移动到另一部分。在本小节中,我们将提供一些基本示例,但是要完整赏析jQuery DOM的能力,需要仔细精读其API参考,并做一些细心的试验。清单20-15演示了在DOM中创建新元素,并用jQuery对表格添加一个新列,以表示山峰的英尺高度。
Listing 20-15. Adding New Elements to the DOM
清单20-15. 对DOM添加新元素
<script type="text/javascript"> $(document).ready(function () { $('table').addClass('summitTable'); $('tr:even').css('background-color', 'silver'); $(':submit[value="Reset"], a:contains("Add")') .css('float', 'left') .css('margin', '5px'); $('th:nth-child(2)').text('Height (m)').after('<th>Height (ft)</th>'); $('td:nth-child(2)') .after('<td/>') .each(function () { $(this).next().text((parseInt($(this).text()) * 3.28).toFixed(0)); }); }); </script>
There are only two new statements in this script, but because of the expressive nature of jQuery and the support for method chaining, there is a lot going on. Let’s start with the first statement:
在这个脚本里只有两条新语句,但是根据jQuery的表现性质以及对方法链的支持,这里实际上做了很多事。让我们从第一条语句开始:
$('th:nth-child(2)').text('Height (m)').after('<th>Height (ft)</th>');
We start by selecting those th elements that are the second children of their parent. The only set of th elements in our sample HTML is in the table element, and the one that is the second child is the Height header. We use the text method to set the text context of the selected element to Height (m) to indicate that this column in the table contains the height of the summits expressed in meters. We then chain the after method that inserts a new element as a peer to the selected element. The parameter for the after method is the element we want to insert, which in this case is a new th element with the text content Height (ft).
我们从选择属于第二个子节点的th元素开始。在示例HTML中,唯一一组th元素是在table元素中,而属于第二个子节点的th是Height表头。我们用text方法把这个选中元素的文本设置成Height(m),以指示该表列包含了以米表示的山峰高度。然后我们链接了after方法,它插入一个与选中元素同辈的新元素。after方法的参数是我们想插入的内容,在这个例子中是一个新的th元素,其文本内容为Height(ft)。
When we use the after method, the new element is inserted after each selected element. We selected only one th element, so only one new element was created. With the second jQuery statement, however, we created several:
当我们使用after方法时,新元素被插入各个选中元素之后。我们只选择了唯一一个th元素,因此,只创建一个新元素。然而,根据第二条jQuery语句,我们创建了几个新元素:
$('td:nth-child(2)') .after('<td/>') .each(function () { ... });
The selector in this statement matches any td element that is the second child of its parent. We are selecting the td elements from the Height column (which has now been renamed Height (m), of course).
这条语句中的选择器挑出的是属于第二个子节点的所有td元素(实际上,选择器选中的是表格中的所有td元素,过滤器挑出的是其中充当第二个子节点角色的各个td元素,因此,最终选出的是表格中所有第二列td元素 — 译者注)。我们选择的是Height列td元素(当然,现在已经被重命名为Height(m)了)。
We then chain a call to the each method, which accepts as its parameter a function that will be executed for each selected element. Our function contains a single statement:
我们然后链接了一个对each方法的调用,它接受的参数是一个function(函数),这个function将针对每个选中元素执行。这个function只含有一条语句:
$(this).next().text((parseInt($(this).text()) * 3.28).toFixed(0));
We start with a special selector, $(this), which creates a selection that contains the element currently being processed. The function we pass to the each method is executed once for each selected element, and this refers to the element that the function is being called for. We need to pass this to the main jQuery function so that we can call methods on the element. In this case, the selector this will refer to each of the td elements that we queried for initially.
我们以一个特殊的选择器$(this)开始,它创建了一个对当前被处理元素的选择。我们传递给each方法的function对每个选中元素都执行一次,而且this指向的是正在调用function的元素。我们需要把这个this传递给jQuery的主函数,以便我们能够在元素上调用方法。在这个例子中,选择器this将指向我们最初查询的每个td元素。
We call the next method to select the sibling immediately after the current element. This gives us the element we just created. We then use the text method to get the text content of one td element and to set the content of another. We calculate the height in feet in the client (1 meter is 3.28 feet).
我们调用next方法来选择紧接于当前元素之后的同胞节点,正是我们刚刚创建的元素(用after创建的td元素 — 译者注)。我们然后用text方法获取一个td元素的文本内容,并设置成另一个内容(这句的意思说得不太明确,请这样理解:this是表格的第二列,next方法指下一个节点,即第三列,text方法是为第三列赋值,这个值取自第二列的文本,并对其进行换算(将米换算成英尺),所得的结果作为第三列的文本内容 — 译者注)。我们在客户端计算了英尺高度(1米=3.28英尺)(请读者注意,这条语句中的this是表格的第二列单元格 — 译者注)。
Figure 20-7 shows the new column.
图20-7显示了这个新列。
Figure 20-7. Adding new content using jQuery
图 20-7. 用jQuery添加新内容
We picked this example for two reasons. The first is it uses different types of jQuery DOM methods. We use after to create a new element and next to navigate through the DOM. The second reason is that there are several different ways of performing the task. This is not uncommon in jQuery, where we can combine different methods to similar effect. Listing 20-16 shows an alternative script that adds the new column.
我们挑选这个例子有两个原因。第一是它使用了不同类型的jQuery DOM方法。我们用after创建了一个新元素,而用next导航DOM。第二个原因是执行该任务有几种不同方式。把不同方法组合成类似效果,这在jQuery中并不少见。清单20-16显示添加新列的另一种脚本。
Listing 20-16. An Alternative Approach to Adding Content to the Summits Table
清单20-16. 给Summits表添加内容的另一种可选方法
$('th:nth-child(2)').text('Height (m)').after('<th>Height (ft)</th>'); $('td:nth-child(2)').each(function () { var height = (parseInt($(this).text()) * 3.28).toFixed(0); $('<td/>').insertAfter($(this)).text(height).css('border', 'thin solid red'); });
The key difference is the statement shown in bold. In the previous example, we used the after method. The result of this method is the selected element, not the element we just created. Any method that we chain to after will be applied to the original element. The statement in Listing 20-16 uses the insertAfter method, which has the same effect as after but returns the newly created element, meaning that any chained methods are applied to the new element and not the existing one (you will also notice that we specify the new element in the main jQuery function and the existing element as the parameter to the insertAfter method). This means we can apply methods to the newly created elements without having to select them or navigate to them. As a demonstration, we added a CSS border, as shown in Figure 20-8.
关键区别是黑体显示的语句。在前面的示例中,我们使用了after方法。该方法的结果是被选中元素,而不是我们刚刚创建的元素。我们链接到after的任何方法都被运用到原先的元素。清单20-16中的语句使用了insertAfter方法,它与after有同样的效果,但返回的是新创建的元素,意即,任何链接的方法都运用于新元素,而不是当前元素(还要注意到,我们在jQuery主函数中指定了新元素,而当前元素是作为参数送给insertAfter方法的)。这意味着我们可以将方法作用到新创建的元素上,而不必选中或导航到它们。作为一个演示,上例我们添加了一个CSS边框,如图20-8所示。
Figure 20-8. A different approach to creating elements
图20-8. 利用不同方法创建元素
The point is that there are often different ways to achieve the same goal, and it is worth experimenting with varying approaches to find one that does what you need in a way that is robust and you are comfortable with. Table 20-9 shows some common jQuery DOM-related manipulation, but quite a number are available, and you should consult the jQuery API reference for the full set.
这一点说明,通常有不同方式来获取同样的目标,而且,对各种办法进行试验,以找到一种你所需要的健壮且舒适的方法,是值得的。表20-9列出了一些常用的jQuery的DOM相关操作,但还有更多可用的,而且,你应该查阅jQuery API参考以获取完整信息。
Method 方法 |
Description 描述 |
---|---|
before('new') after('new') |
Inserts the element new either before or after the selected elements. 将new元素插入在选中元素之前,或之后。 |
insertBefore() insertAfter() |
As for before and after, but the order of the new element and the selector is reversed, and these methods return the newly created elements. See Listing 20-16 for an example. 相当于before和after,但新元素与选择器的顺序是相反的,而且这些方法会返回新创建元素。参见清单20-16示例。 |
prepend('new') append('new') |
Inserts the element new inside of the selected elements, either as the first or last child. 在选中元素内部插入new元素,作为第一个子节点,或最后一个子节点。 |
prependTo() appendTo() |
As for prepend and append, but the order of the new element and the selector is reversed, and these methods return the newly created elements. 相当于prepend和append,但new元素和选择器的顺序是相反的,而且这些方法会返回新创建元素。 |
empty() | Removes all children from the selected elements. 清空选中元素的所有子节点。 |
remove() | Removes the selected elements from the DOM. 从DOM中移除选中元素。 |
attr('name', 'val') | Sets the attribute name to value val on the selected elements; will create the attribute if it doesn’t already exist. 在选中元素上将name属性的值设置为val。如果不存在name属性,则创建它。 |
removeAttr('name') | Removes the attribute name from the selected elements. 删除选中元素的name属性 |
jQuery also defines a set of methods for navigating around the DOM. Table 20-10 shows some of the most commonly used of these.
jQuery还定义了一组对DOM导航的方法。表20-10列出了一些最常用的方法。
Method 方法 |
Description 描述 |
---|---|
children() | Gets the children of the selected elements 获取选中元素的子节点 |
next() | Gets the sibling elements that immediately follow the selected elements 获取紧随选中元素之后的同胞元素 |
prev() | Gets the sibling elements that immediately precede the selected elements 获取紧邻选中元素的前一个同胞元素 |
parent() | Returns the immediate parents of the selected elements 返回选中元素的上一级父节点 |
sibilings() | Returns the siblings of the selected elements 返回选中元素的同胞节点 |
The navigation methods accept an optional selector parameter; only elements that match the selector will be returned as results.
这些导航方法接收一个可选的选择器参数,只有与选择器匹配的元素才会被作为结果返回。
Using jQuery Events
使用jQuery事件
The jQuery library includes a nice event handling system that supports all the underlying JavaScript events but makes them easier to use, consistent across browsers, and compatible with selectors. Listing 20-17 contains a demonstration.
jQuery库含有一个很好的事件处理系统,它支持所有底层JavaScript事件,但使它们更易于使用、跨浏览器一致、且与选择器兼容。清单20-17含有一个演示。
Listing 20-17. Using jQuery Events
清单20-17. 使用jQuery事件
<script type="text/javascript"> $(document).ready(function () { $('table').addClass('summitTable'); $('tr:even').css('background-color', 'silver'); $(':submit[value="Reset"], a:contains("Add")') .css('float', 'left') .css('margin', '5px'); $('th:nth-child(2)').text('Height (m)').after('<th>Height (ft)</th>'); $('td:nth-child(2)') .after('<td/>') .each(function () { $(this).next().text((parseInt($(this).text()) * 3.28).toFixed(0)); }); $('form[action$="/DeleteSummit"]').submit(function () { var summitName = $(':hidden', this).attr('value'); return confirm('Are you sure you want to delete ' + summitName + ' ?'); }); }); </script>
In this example, we have used the submit method to register a function that will be called when a form is submitted. We have selected those forms whose action attribute value ends with /DeleteSummit, which is the set of forms embedded within the HTML table and which are responsible for deleting individual summits from the list.
在这个例子中,我们用submit方法注册了一个函数,它将在表单被递交时调用。我们选择了这样一些表单,它们的action属性值以/DeleteSummit结尾,这是嵌入在HTML表格中的一组表单,并负责删除列表中的个别山峰。
The result that we return from the function determines whether the form will be submitted. If we return true, it will; if we return false, it won’t. In this example, we generate a result by using the confirm function, which prompts the user, as shown in Figure 20-9.
这个函数的返回结果决定是否递交此表单。如果返回true则递交,返回false则不递交。在这个例子中,通过使用confirm函数,我们生成了一个结果,用来对用户进行提示,如图20-9所示。
Figure 20-9. Prompting the user before deleting a summit from the list
图20-9. 在删除列表中一个山峰之前提示用户
In this way, we have added a prompt that requires the user to confirm that they want a summit to be deleted before the form is submitted. Notice how easy it was to add the event handler to all the selected form elements. We just use a regular jQuery selector and called the submit method to register our function. jQuery takes care of everything else. jQuery supports all the underlying JavaScript events; for full details, consult the jQuery API reference.
在这种方式中,我们添加了一个提示,以便在表单被递交之前,让用户对他们想删除的山峰进行确认。注意,把事件处理程序添加到选中的form元素是多么容易。我们只要使用一个常规的jQuery选择器,并调用submit方法来注册我们的函数。剩下的都由jQuery去考虑。jQuery支持所有底层的JavaScript事件,完整细节请查阅jQuery API参考。
Using jQuery Visual Effects
使用jQuery视觉效果
The jQuery library includes some basic, but effective, visual effects. These are not a substitute for the full glory that is jQuery UI (see the next section for details), but they are useful for simple tasks, and they have the advantage of not requiring any additional library files. Listing 20-18 shows a script that relies on some visual effects.
jQuery库包含了一些最基本却有效的视觉效果(意即,这些效果不那么丰富,或不尽如人意 — 译者注)。这些不能掩盖jQuery UI的整个荣誉(详见下一小节),但它们对有一些简单任务是有用的,而且它们具有不需要任何附加库文件的好处。清单20-18演示一个依赖于某些视觉效果的脚本。
Listing 20-18. Using jQuery Visual Effects
清单20-18. 使用jQuery视觉效果
<script type="text/javascript"> $(document).ready(function () { $('table').addClass('summitTable'); $('tr:even').css('background-color', 'silver'); $(':submit[value="Reset"], a:contains("Add")') .css('float', 'left') .css('margin', '5px'); $('<th>Height (ft)</th>').insertAfter('th:nth-child(2)').addClass("heightFt"); $('<td/>') .insertAfter('td:nth-child(2)') .each(function () { $(this).text((parseInt($(this).prev().text()) * 3.28).toFixed(0)); }) .addClass('heightFt'); $('<button>Toggle Feet</button>').insertAfter('form[action$="/ResetSummits"]') .css('float', 'left') .css('margin', '5px') .click(function () { $('.heightFt').toggle(); }); }); </script>
We have constructed the table column so that the th and td elements are all assigned the heightFt class. We then create a button element, insert it into the document, and register a handler function fort the click method, which is invoked when the button is clicked and released.
我们已经构造了表格列,以使th和td元素的class全部赋了heightFt值。然后我们创建一个button元素,把它插入文档,并为click方法注册了一个处理函数,它将在这个按钮被点击并释放时被调用。
The visual effect is shown in bold. We select all the elements that have been assigned to the heightFt class and call the toggle method. If the elements are visible, jQuery will hide them; if they are not visible, jQuery will show them on the page. Figure 20-10 shows the effect.
视觉效果以黑体显示。我们选择了class为heightFt的所有元素,并调用toggle方法。如果这些元素是可见的,jQuery将隐藏它们,反之,jQuery将把它们显示在页面上。图20-10演示了其效果。
Figure 20-10. Toggling the visibility of elements
图20-10. 切换元素的可视性
The toggle method switches the visibility of elements immediately, but jQuery also provides support for simple animated transitions. Had we used the fadeToggle method instead, the table column would gracefully fade in and out. Table 20-11 describes the most commonly used visual effects.
toggle方法立即切换元素的可视性,但jQuery也提供了对简单动画转换的支持。如果我们用fadeToggle方法来代替,表格列会淡入淡出。表20-11描述了最常用的视觉效果。
Method 方法 |
Description 描述 |
---|---|
fadeIn() | Gradually displays selected elements by increasing opacity 通过增加不透明度逐渐显示选中元素 |
fadeOut() | Gradually hides selected elements by decreasing opacity 通过降低不透明度逐渐隐藏选中元素 |
fadeTo() | Fades the elements to a specified opacity 将元素淡化到指定的不透明度 |
fadeToggle() | Gradually shows or hides elements by changing opacity 通过改变不透明度逐渐显示或隐藏元素 |
hide() | Immediately hides selected elements 立即隐藏选中元素 |
show() | Immediately shows selected elements 立即显示选中元素 |
slideDown() | Shows elements by animating them with a sliding motion down the page 以下滑到页面的动画显示元素 |
slideToggle() | Shows or hides elements with a sliding effect 用滑动效果显示或隐藏元素 |
slideUp() | Shows elements by animating them with a sliding motion up the page 以上滑到页面的动画显示元素 |
toggle() | Immediately hides elements that are visible and shows elements that are hidden 立即隐藏可见元素,或显示隐藏元素 |
Some of the visual effect methods take optional parameters that allow us to exert control over the way that the effects are performed, for example, by specifying the time period over which the visibility of the selected elements is changed.
有些视觉效果方法采用可选参数,以便对效果的执行方式施加一些控制,例如,对选中元素可视性变化指定时间周期。
■ Tip jQuery also defines a general-purpose animate method, which can be used to alter CSS properties over time. See the jQuery API reference for details.
提示:jQuery也定义一个多用途的动画方法,它可以随时用于改变CSS属性。详见jQuery API参考。
Using jQuery UI
使用jQuery UI
The scope and features of JavaScript libraries has exploded in recent years, and a good example of this is jQuery UI, which is a user interface toolkit built by the jQuery team on top of the core jQuery library. A good JavaScript UI toolkit, such as jQuery UI, allows us to build web applications that have more dynamic user controls and to further extend the visual theme of our pages.
近年来,JavaScript库的范围和特性已经得到爆炸性发展,有关这方面的一个很好的例子是jQuery UI(jQuery的用户界面),它是jQuery团队建立在核心jQuery库之上的用户界面工具包。一个良好的JavaScript UI工具包,如jQuery UI,让我们能够建立更具动态用户控制并能对页面视觉主题进一步扩展的web应用程序。
The jQuery UI library has a lot of features, everything from drag and drop to special effects for making elements and widgets move, pulse, and flash on and off—and, of course, a set of rich widgets for improving user interactions. We can’t do jQuery UI justice in this chapter. There is extensive documentation available at http://jqueryui.com, and we recommend Dan Wellman’s book jQuery UI, published by Packt Publishing, if you want a more tutorial-based approach to the library.
jQuery UI库有许多特性,从拖放到各种特殊效果(使元素及插件移动、脉动、以及闪入闪出)等方方面面 — 当然,还有一组用来改善用户交互的富插件。本章我们不能演示jQuery UI。在http://jqueryui.com上有丰富的可用文档,而且,如果你希望有一个更教程化的方法了解这个库,我们推荐Dan Wellman的图书《jQuery UI》,Packt Publishing出版。
Referencing jQuery UI
引用jQuery UI
To add jQuery UI to our MVC Framework applications, we have to add two references. The first reference is to the jQuery UI library file, and the second is to the CSS file that contains the theme that will be used. As with the main jQuery library, we can add these to individual views or to a view if we intend to use it throughout an application. Listing 20-19 shows the additions we have made to the ~/Views/Shared/_Layout.cshtml file.
为了把jQuery UI添加到我们的MVC框架应用程序,必须添加两个引用。第一个是引用jQuery UI库文件,第二个是引用CSS文件,它含有使用这些UI的主题样式。就像引用主jQuery库一样,我们可以把这些引用添加到单个视图,或添加到一个打算运用于整个应用程序的视图(如布局视图 — 译者注)。清单20-19显示了我们在~/Views/Shared/_Layout.cshtml文件中所做的添加。
Listing 20-19. Referencing the jQuery UI Library and CSS Files
清单20-19. 引用jQuery UI库和CSS文件
<!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery-ui.min.js")" type="text/javascript"></script> <link href="@Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" /> </head> <body> @RenderBody() </body> </html>
Both files must be added. jQuery UI won’t work without the CSS files. The main jQuery library must be referenced as well, since jQuery UI relies on jQuery.
这两个文件都必须添加。没有这个CSS文件,jQuery UI不会起作用。主jQuery库也必须引用,因为jQuery UI依赖于jQuery。
USING THEMEROLLER
使用ThemeRoller
jQuery UI has very strong support for themes, which control the look and feel of all of the widgets and effects that jQuery UI contains. You can create a custom theme by using the jQuery UI ThemeRoller tool, which is available at http://jqueryui.com/themeroller. You can also create a custom jQuery UI library that contains your theme and elect only to include those components that you require in your application. This can be used to reduce the size of the library that your clients must download, although if library size is a concern, you may be better served by using a CDN.
jQuery UI对主题具有很强的支持,这些主题控制jQuery UI包含的所有插件和效果的感观。你可以通过使用jQuery UI的ThemeRoller工具来创建自定义主题,该工具可在http://jqueryui.com/themeroller下载。你也可以创建包含你的主题的自定义jQuery UI库,并选择只包含你应用程序需要的那些组件。这可以用来减小客户端必须下载的库文件的大小,当然,如果库大小需要关注,你可能最好使用CDN服务。
Making Better Buttons
制作更好的按钮
One of our favorite jQuery UI features is also one of the simplest: the ability to create themed buttons to enhance HTML elements. Listing 20-20 contains an example.
我们比较喜欢的jQuery UI特性之一也是最简单的一个:创建主题式按钮以增强HTML元素的能力。清单20-20包含了一个示例。
Listing 20-20. Using the jQuery UI Buttons Feature
清单20-20. 使用jQuery UI的按钮特性
<script type="text/javascript"> $(document).ready(function () { $('table').addClass('summitTable'); $('tr:even').css('background-color', 'silver'); $('<th>Height (ft)</th>').insertAfter('th:nth-child(2)').addClass("heightFt"); $('<td/>') .insertAfter('td:nth-child(2)') .each(function () { $(this).text((parseInt($(this).prev().text()) * 3.28).toFixed(0)); }) .addClass('heightFt'); $('<button>Toggle Feet</button>').insertAfter('form[action$="/ResetSummits"]') .click(function () { $('.heightFt').toggle(); }); $('a, :submit').button().css('float', 'left').css('margin', '5px'); }); </script>
You can see from the statement shown in bold that jQuery UI works with the standard jQuery selectors and filters. In this example, we have selected the anchor (a) elements and all those input elements whose type is submit. We then call the button method to apply the jQuery UI button feature, the results of which are shown in Figure 20-11.
你可以从以黑体显示的语句看出,jQuery UI使用标准的jQuery选择器和过滤器。在这个例子中,我们选择了锚点(a)元素和那些type为submit的所有input元素。然后我们调用button方法来运用jQuery UI的按钮特性,其结果如图20-11所示。
Figure 20-11. The effect of the jQuery UI button feature
图20-11. jQuery UI按钮特性的效果
As you can see from the figure, the button method applies a consistent button appearance to the selected elements. The buttons that we created in this example are fully formed, meaning that all the events required to adapt the button to the underlying HTML elements are taken care of for us automatically.
由图可见,button方法把一致的按钮外观运用于选中元素。我们在这个例子中创建的按钮是全形式的,意即,使按钮与底层HTML元素适应所需要的所有事件都自动得到照应(意即不会改变按钮的底层特性 — 译者注)。
■ Tip These buttons are themed, which means their appearance will be consistent with other jQuery UI widgets. Unfortunately, the default theme is, well, pretty dull. See the “Using ThemeRoller” sidebar for details of creating more visually appealing jQuery UI themes.
提示:这些按钮是主题式的,意即,它们的外观与其它jQuery UI插件是一致的。不幸的是,默认主题是相当呆板的。详见说明“使用ThemeRoller”,创建更具视觉效果的jQuery UI主题。
Using a Slider
使用滑块
Our second example in this section shows how jQuery UI interoperates nicely with the underlying jQuery functionality, in particular events, visual effects, and, of course, selectors. We are going to add a ranged slider to the page that will allow us to filter the set of summits displayed in the table based on their heights.
本小节的第二个示例演示了jQuer UI与底层jQuery功能如何进行良好的交互操作,特别是与事件、视觉效果,当然还有选择器。我们打算把一个范围滑块添加到页面,它允许我们基于山峰的高度,对表格中显示的一组山峰进行过滤。
To begin with, we have added some additional HTML elements to the page on which we will build our new feature, as shown in Listing 20-21.
首先,我们在页面上添加了一些附加HTML元素,并准备这些元素上构建我们的新特性,如清单20-21所示。
Listing 20-21. Adding Elements to Support the Slider
清单20-21. 添加支持滑块的元素
... </table> <label id="min">5000</label> <div id="slider"></div> <label id="max">9000</label> <div style="clear:both" /> @Html.ActionLink("Add", "AddSummit") @using (Html.BeginForm("ResetSummits", "Home")) { <input type="submit" value="Reset" /> }
We could have generated these elements dynamically, but we wanted to demonstrate that jQuery and jQuery UI can work equally as well with the HTML generated by the application. We have added a couple of label elements that we will use to display the range of summit heights and a div that jQuery UI will use to display the slider. We have also added a div to control the page layout.
我们可以动态生成这些元素,但我们想演示jQuery和jQuery UI可以与应用程序生成的HTML工作得一样良好。我们添加了两个label元素,将用来显示山峰的高度范围,还有一个jQuery UI用来显示滑块的div。另外还添加了一个div以控制页面的布局(指黑体中的第二个div — 译者注)。
With the elements in place, we can add the slider feature to our script, as shown in Listing 20-22.
通过这些适当就位的元素,我们可以把滑块特性添加到脚本,如清单20-22所示。
Listing 20-22. Using a Slider to Control the Table Contents
清单20-22. 使用滑块来控制表格内容
<script type="text/javascript"> $(document).ready(function () { $('table').addClass('summitTable'); $('tr:even').css('background-color', 'silver'); $('<th>Height (ft)</th>').insertAfter('th:nth-child(2)').addClass("heightFt"); $('<td/>') .insertAfter('td:nth-child(2)') .each(function () { $(this).text((parseInt($(this).prev().text()) * 3.28).toFixed(0)); }) .addClass('heightFt'); $('<button>Toggle Feet</button>').insertAfter('form[action$="/ResetSummits"]') .click(function () { $('.heightFt').toggle(); }); $('a, :submit').button().css('float', 'left').css('margin', '5px'); $('#slider').slider({ range: true, min: 5000, max: 9000, values: [5000, 9000], slide: function (event, ui) { $('#min').text(ui.values[0]); $('#max').text(ui.values[1]); $('tbody tr').each(function () { var height = parseInt($('td:eq(1)', this).text()); if (height < ui.values[0] || height > ui.values[1]) { $(this).hide(); } else { $(this).show(); } }); $('tr:visible:even').css('background-color', 'silver'); $('tr:visible:odd').css('background-color', 'transparent'); } }); }); </script>
We create the jQuery UI slider by selecting the div element we added to the view and calling the slider method, and we configure it by passing in options. For our example, we want a ranged slider, where there are two handles that represent the upper and lower bounds of a range. We do this by setting the range option to true. We have hard-coded the upper and lower bounds of the range using the min and max options and the initial positions of the handles using the values option. All of these options (and many more) are described on the jQuery UI web site.
通过选择添加到视图的div元素(其id="slider"的那个div — 译者注),并调用slider方法,我们创建了一个jQuery UI滑块,并通过在其中传递一些选项对它进行配置。例如,我们想要一个范围滑块,它有两个句柄来表示范围的上界和下界。这是通过把range选项设置为true来实现的。接着用min和max选项对范围的上下界进行硬编码,并用values选项设定了句柄的初始位置。所有这些选项(还有更多)都在jQuery UI的web网站作了描述。
We use the slide option to register a function that will be called each time the value of the slider changes. Our function is passed the event and a reference to the UI component. This function is the way in which we integrate the slider into the rest of the page. We’ll go through the function step by step, starting with these statements:
我们用slide选项注册了一个函数,它将在滑块的值每次发生变化时被调用。给这个函数传递了event和一个对UI组件的引用。该函数是我们把滑块集成到页面上的方式。我们来一步步说明这个函数,先从这些语句开始:
$('#min').text(ui.values[0]); $('#max').text(ui.values[1]);
We pass the values method of the ui parameter to the function to get the current position of the slider values and update the label elements that we added to the view in Listing 20-21. We do this to give the user some visual feedback about the filter they have applied to the list of summits. We then perform the actual filtering operation:
我们给这个函数传递了ui参数,通过对这个ui运用values方法,以获取滑块值的当前位置,并对添加到清单20-21视图的label元素进行更新。这么做给用户提供了一些视觉反馈,这些反馈是关于运用于山峰列表过滤器的(滑块两端显示的数字值 — 译者注)。然后我们执行实际的过滤操作:
$('tbody tr').each(function () { var height = parseInt($('td:eq(1)', this).text()); if (height < ui.values[0] || height > ui.values[1]) { $(this).hide(); } else { $(this).show(); } });
We select all the tr elements contained in the table body and use the each method to obtain the height of the summit that the row displays. If the height is inside the range that the user has created in the slider, we call the show method. If not, we call the hide method to remove it from the page.
我们选择了包含在表格体中的所有tr元素,并用each方法来获取表行所显示的山峰高度。如果该高度落在用户创建的滑块的范围之内,便调用show方法。否则,调用hide方法将其从页面中删除。
■ Tip We could make this process more efficient by extracting the table rows and the heights they contain, rather than selecting and parsing each time the slider changes. This could be done using the jQuery map method; see the jQuery API reference for details.
提示:我们可以通过提取表行及其含有的高度,而不是选择并解析每次的滑块变化,使这一过程更加高效。这可以用jQuery的map方法来实现,详见jQuery API参考。
Finally, we reapply the zebra-striping to the table, as follows:
最后,我们对表格再次运用了斑马条纹,如下所示:
$('tr:visible:even').css('background-color', 'silver'); $('tr:visible:odd').css('background-color', 'transparent');
Bear in mind that we are adding and removing rows from the table as the user moves the handles in the slider. This means we can end up with consecutive rows that have the same background color. We fix this by filtering for those rows that are visible, applying a color to the even rows, and removing any coloring from the odd rows.
要记住的是,我们添加和删除表行是在用户移动滑块句柄的时候。这意味着我们最终可能会得到一些具有同样背景色的连贯表行。通过对可见的表行进行过滤、把一种颜色运用于偶数表行、并删除奇数表行的颜色,我们可以修正这一问题。
The net result of this is that we have added a slider that dynamically modifies the visibility of rows in the HTML table based on the range that the user specified, as shown in Figure 20-12.
最终结果是我们添加了一个滑块,它基于用户指定的范围动态地修改HTML表格中各表行的可视性,如图20-12所示。
Figure 20-12. Dynamically altering table row visibility using a jQuery UI slider
图20-12. 用jQuery UI滑块动态改变表行可视性
Summary
小结
jQuery and jQuery UI are powerful, flexible, and feature-packed libraries that we can use to improve the client-side experience of our users. We have barely scratched the surface of what these libraries can do, and we suggest you take the time to look at http://jquery.com and http://jqueryui.com to learn more about the features and APIs available.
jQuery和jQuery UI是强大、灵活、和按功能组包的库,可以用于改善用户的客户端体验。我们仅仅初浅尝试了这些库可做的事情,我们建议你花一些时间看看http://jquery.com和http://jqueryui.com,以了解更多可用的特性和API。