面向设计师的-jQuery-入门指南-全-

面向设计师的 jQuery 入门指南(全)

原文:zh.annas-archive.org/md5/FFDF3B70B19F674D777B2A63156A89D7

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

感谢阅读jQuery for Designers。本书旨在面向具有基本 HTML 和 CSS 理解的设计师,但希望通过学习一些基本 JavaScript 来提升他们的技能。即使你以前从未尝试过编写 JavaScript,本书也将引导你完成设置一些基本 JavaScript 和完成常见任务的过程,如折叠内容、下拉菜单、幻灯片等,这都要归功于 jQuery 库!

本书涵盖内容

第一章,设计师,遇见 jQuery,是对 jQuery 库和 JavaScript 的介绍。你将了解到 jQuery 的崛起,为何对设计师如此重要,以及如何在不需要学习大量代码的情况下创建一些花哨的特效。本章还包括对 JavaScript 的简要介绍,并引导你编写第一个 JavaScript 代码。

第二章,增强链接,将引导你完成一些基本的链接增强。你将学习如何使用 jQuery 在新窗口中打开链接,如何为链接添加图标,以及如何将一组链接转换为选项卡界面。

第三章,制作更好的常见问题解答页面,将介绍如何折叠和显示内容,以及在 HTML 文档中移动从一个元素到另一个元素。在本章中,我们将设置一个基本的常见问题解答列表,然后逐步增强它,使我们的网站访问者更容易使用。

第四章,构建自定义滚动条,是我们对 jQuery 插件的第一次介绍。我们将使用 jScrollPane 插件创建在几种不同浏览器中按预期工作的自定义滚动条。我们将看看如何设置滚动条,自定义它们的外观,并实现动画滚动行为。

第五章,创建自定义工具提示,介绍了如何使用 qTip 插件替换浏览器的默认工具提示为自定义工具提示。然后我们进一步创建自定义工具提示来增强导航栏,并使用工具提示显示额外内容。

第六章,构建交互式导航菜单,将指导你设置功能完善且视觉上令人惊叹的下拉和飞出菜单。我们将逐步讲解使这些类型的菜单工作所需的复杂 CSS,使用 Superfish 插件填补纯 CSS 解决方案缺失的功能,并看看如何自定义菜单的外观。

第七章, 异步导航,介绍了 Ajax,并展示了如何使用一点 jQuery 将简单网站转换为单页面 Web 应用程序。首先,我们设置了一个简单的示例,然后逐步介绍了一个更全面的示例,其中包括对传入链接和返回按钮的支持。

第八章, 展示灯箱中的内容,将为您介绍如何使用 Colorbox jQuery 插件在灯箱中展示照片和幻灯片。一旦我们掌握了基础知识,我们还将学习如何使用 Colorbox 插件来创建一个精美的登录界面,播放一系列视频,甚至搭建一个单页面网站画廊。

第九章, 创建幻灯片,将会介绍创建图像幻灯片的几种不同方法。首先,我们将介绍一个从头开始构建基本淡入淡出幻灯片的例子。然后,我们将学习如何使用 CrossSlide 插件、Nivo Slider 插件和 Galleriffic 插件创建不同类型的幻灯片。

第十章, 在走马灯和滑块中展示内容,介绍了使用 jCarousel jQuery 插件构建走马灯、新闻滚动和滑块。我们将创建一个水平走马灯、垂直新闻滚动和特色内容滑块。然后,我们将看看当我们将幻灯片集成到走马灯中时,插件如何被进一步扩展。

第十一章, 创建交互式数据网格,介绍了如何将简单的 HTML 表格转换为完全交互式的数据网格,从而使您的网站访问者能够浏览表格、搜索条目,并按不同的列进行排序。

第十二章, 改进表单,探讨了如何改进表单。本章将指导您正确设置 HTML 表单,使用最新的 HTML5 表单元素。然后,我们通过将光标放在第一个字段中、使用占位符文本和验证网站访问者的表单输入来增强表单。最后,我们将了解 Uniform jQuery 插件,该插件允许我们为了在不同的浏览器中实现一致的表单外观而给最难以应对的表单元素添加样式。

你需要准备什么

你需要一个文本编辑器来创建 HTML、CSS 和 JavaScript。一些很好的免费选项是 Mac 上的 TextWrangler 或 Windows 上的 Notepad++。还有许多其他选择可供选择,你可以随意使用你喜欢的文本编辑器来运行本书中的任何示例。

你还需要一个浏览器。我个人最喜欢的是 Google Chrome,它包含了对 CSS 和 JavaScript 非常有帮助的调试工具。同样,你也可以随意选择你喜欢的浏览器来运行本书中的示例。

如果您想为自己的设计创建图像,那么 Adobe Photoshop 和 Adobe Illustrator 将会很有帮助,尽管它们并非必须。 本书示例代码中使用的所有示例所需的图像都已包含在内。

本书适合谁

本书适合那些具有 HTML 和 CSS 基本理解的设计师,但希望通过学习使用 JavaScript 和 jQuery 来扩展他们的知识。

约定

在本书中,您会经常看到几个标题。

为了清晰地说明如何完成一个过程或任务,我们使用:

行动时间 — 标题

  1. 行动 1

  2. 行动 2

  3. 行动 3

说明通常需要一些额外的解释,以便它们有意义,因此它们后面跟着:

刚刚发生了什么?

此标题解释了您刚刚完成的任务或说明的工作原理。

在本书中,您还会找到一些其他的学习辅助工具,包括:

快速测验 — 标题

这些是短的多项选择题,旨在帮助您测试自己的理解。

尝试一下 — 标题

这些设定了实际挑战,并给出了您学到的东西的实验想法。

您还会发现一些文本样式,用于区分不同类型的信息。 以下是这些样式的一些示例及其含义的解释。

文本中的代码词如下所示:"jQuery 对象的 filter() 方法将允许我们过滤先前选择的一组元素。"

代码块设置如下:

$('#tabs a').bind('click', function(e){
$('#tabs a.current').removeClass('current');
$('.tab-section:visible').hide();

当我们希望引起您对代码块特定部分的注意时,相关行或项目将以粗体显示:

$(this.hash).show();
$(this).addClass('current');
e.preventDefault;
}).filter(':first').click();

新术语重要单词 以粗体显示。 例如,在屏幕上看到的词语、菜单或对话框中出现的词语会在文本中显示为:"有人认为在新窗口中打开链接会破坏 返回 按钮的预期行为,因此应该避免这样做。"

注意

警告或重要提示会以如下的方式显示:

小贴士

小贴士和技巧会以这种方式显示。

第一章:设计师,遇见 jQuery

在过去几年里,你可能已经听说了很多关于 jQuery 的事情 —— 它很快成为了当今网络上使用最广泛的代码包之一。你可能会想知道这一切到底是怎么回事。

无论你以前是否尝试过理解 JavaScript 并因挫折而放弃,或者对此感到害怕而不敢尝试,你会发现 jQuery 是一种非常易于接近且相对容易学习的方法,可以让你初次接触 JavaScript 时感到轻松自如。

在这一章中,我们将涵盖:

  • jQuery 是什么,为什么它非常适合设计师

  • 渐进增强和优雅降级

  • JavaScript 基础知识

  • 下载 jQuery

  • 你的第一个 jQuery 脚本

jQuery 是什么?

jQuery 是一个 JavaScript 库。这意味着它是一组可重复使用的 JavaScript 代码,用于完成常见任务 —— 网页开发者经常发现自己一遍又一遍地解决相同的问题。与其每次从头开始设计解决方案,不如将所有这些有用的代码片段收集到一个单独的包中,可以在任何项目中包含并使用。jQuery 的创建者已经编写了代码来平稳而轻松地处理我们想要使用 JavaScript 完成的最常见和最乏味的任务 —— 并且他们已经解决了在不同浏览器中让代码工作所需解决的所有小差异。

重要的是要记住 jQuery 是 JavaScript,而不是自己的语言。它遵循同样的规则,以及与 JavaScript 相同的写法。不要因此而退缩 —— jQuery 确实使编写 JavaScript 变得更加容易。

jQuery 的官方口号是 写更少,做更多。这是对 jQuery 库的一个极好而准确的描述 —— 你真的可以在几行代码中完成惊人的事情。我自己对 jQuery 的非官方口号是 找到东西并对其进行操作,因为使用原始 JavaScript 找到并操作 HTML 文档的不同部分非常乏味,并且需要大量的代码行。jQuery 使得同样的任务变得轻松而快速。多亏了 jQuery,你不仅可以快速创建一个下拉菜单 —— 你可以创建一个动画效果并且在许多不同的浏览器中流畅运行的下拉菜单。

为什么 jQuery 对设计师来说如此棒?

那么,究竟是什么让 jQuery 如此易于学习,即使你对 JavaScript 有限或没有经验?

使用你已经了解的 CSS 选择器

在 jQuery 脚本中,你通常会做的第一件事情是选择你想要操作的元素。例如,如果你要向导航菜单添加一些效果,你会首先选择导航菜单中的项目。用于这项工作的工具是选择器 —— 一种选择页面上要操作的特定元素的方法。

jQuery 从 CSS 中借用了选择器一直到 CSS3,即使在尚不支持 CSS3 选择器的浏览器中也可以工作。

尽管 CSS 提供了一组相当强大的选择器,但 jQuery 自己添加了一些额外的选择器,使得你需要的元素更容易处理。

如果你已经知道如何做一些事情,比如将所有的一级标题变为蓝色,或者将所有的链接变为绿色并带下划线,那么你很容易学会如何用 jQuery 选择你想要修改的元素。

使用你已经了解的 HTML 标记语言

如果你想要用原始的 JavaScript 创建新元素或修改现有元素,最好揉揉手指,准备好写很多很多的代码 —— 而且这些代码可能并不那么容易理解。

例如,如果我们想要向页面附加一个段落,内容是这个页面由 JavaScript 驱动,我们首先必须创建段落元素,然后将应该在段落中的文本分配给一个变量作为字符串,最后将字符串附加到新创建的段落作为文本节点。然后,我们仍然必须将段落附加到文档中。哎呀!(如果你没有完全理解这一切,别担心,这只是为了说明做这么简单的事情需要多少工作和代码。)

通过 jQuery,向页面底部添加一个段落就这么简单:

$('body').append('<p>This page is powered by jQuery.</p>');

没错 —— 你只需将一小段 HTML 直接附加到 body 中,然后一切就搞定了。我敢打赌,即使你完全不理解 JavaScript,你也能读懂那行代码并理解它在做什么。这段代码是将一个段落附加到我的 HTML 文档的 body 中,内容是这个页面由 jQuery 驱动

仅需几行代码即可实现令人印象深刻的效果。

你有更重要的事情要做,而不是坐在那里写一行一行的代码来添加淡入和淡出效果。jQuery 为你提供了一些基本的动画和创建自定义动画的能力。比如说,我想让一张图片淡入到页面中:

$('img').fadeIn();

是的,就是这样 —— 一行代码,我选择了我的图片然后告诉它淡入。我们稍后会在本章中确切地了解这行代码在你的 HTML 页面中的位置。

可用的巨大插件库

正如我之前所说,Web 开发者经常发现自己反复解决相同的问题。你很可能不是第一个想要构建旋转图片幻灯片、动画下拉菜单或新闻滚动条的人。

jQuery 有一个令人印象深刻的大型脚本库 —— 脚本用于创建工具提示、幻灯片、新闻滚动条、下拉菜单、日期选择器、字符计数器等等。你不需要学会如何从头开始构建所有这些东西 —— 你只需要学会如何利用插件的威力。我们将在本书中介绍一些最受欢迎的 jQuery 插件,你将能够利用你所学到的知识使用 jQuery 插件库中的任何插件。

庞大的社区支持

jQuery 是一个开源项目 — 这意味着它是由一群超级聪明的 JavaScript 编码人员共同构建的,并且任何人都可以免费使用。开源项目的成功或失败通常取决于项目背后的社区 — 而 jQuery 有一个庞大而活跃的支持社区。

这意味着 jQuery 本身正在不断改进和更新。除此之外,还有成千上万的开发人员创建新的插件,为现有插件添加功能,并为新手提供支持和建议 —— 你会发现针对几乎任何你想学习的内容,每天都会有新的教程、博客文章和播客。

JavaScript 基础知识

在本节中,我将介绍一些 JavaScript 的基础知识,这将使事情更加顺利进行。我们将查看一小部分代码,并解释它的工作原理。不要感到害怕 —— 这将很快并且没有痛苦,然后我们将准备好真正开始使用 jQuery 了。

渐进增强和优雅降级

在增强 HTML 页面与 JavaScript 时,有几种不同的思想流派。在我们着手进行有趣的事情之前,让我们谈谈一些在深入研究之前应该考虑的事情。

渐进增强和优雅降级本质上是同一枚硬币的两面。它们都意味着我们的页面及其令人印象深刻的 JavaScript 动画和特效将仍然适用于具有较差浏览器或设备的用户。优雅降级意味着我们创建特效,然后确保如果未启用 JavaScript,则优雅地失败。如果我们采用渐进增强方法,我们将首先构建一个适用于所有人的简约页面,然后通过添加我们的 JavaScript 特效来增强它。我倾向于采用渐进增强方法。

我们为什么要关心那些没有启用 JavaScript 的用户呢?好吧,网络上最大的用户之一 — 搜索引擎 — 没有 JavaScript 功能。当搜索引擎爬行和索引您的页面时,它们将无法访问 JavaScript 加载到您的页面中的任何内容。这通常被称为动态内容,如果无法在禁用 JavaScript 的情况下访问,搜索引擎将无法索引或找到它。

我们也处于一个时代,不再能指望用户使用传统的台式机或笔记本电脑访问我们构建的网页。我们很快就会想到智能手机和平板电脑是下一个候选者,虽然它们非常受欢迎,但它们仍然只占互联网访问的一小部分。

人们从游戏机、电子书阅读器、互联网电视、各种各样的移动设备甚至可能还有数百种其他方式访问网络。并非所有这些设备都能执行 JavaScript —— 其中一些甚至没有彩色屏幕!你的头等大事应该是确保你的内容对任何要求它的人都是可用的,无论他们使用的设备是什么。

必须分开处理它们

要完成这个尽可能使我们的内容对尽可能广泛的受众可用的任务,我们必须将我们的网页看作是三个独立且不同的层次:内容、呈现和行为。

内容

内容是我们网页的重点 —— 它是我们最感兴趣的呈现在我们页面上的文本或音频或视频,所以这是我们开始的地方。

用干净、简单的 HTML 代码标记您的内容。使用 HTML 元素的方式是它们预期的使用方式。使用标题标记标记标题、使用段落标记标记段落、使用列表标记标记列表,并将表格保留给表格数据。

浏览器为这些基本的 HTML 标签内置了样式 —— 标题将会是较大的字体且可能会加粗。列表将具有项目符号或编号。可能看起来不太花哨,但它对任何人来说都是可读的和可访问的。

呈现

展示层是我们开始变得花哨的地方。这是我们引入 CSS 并开始对我们创建的内容应用自己的样式的地方。当我们为页面添加样式时,我们可能会发现我们需要回到我们的 HTML 中添加一些新的容器和标记,以使诸如多列布局之类的东西成为可能,但我们仍然应该努力保持我们的标记尽可能简单和直接。

行为

一旦我们的页面所有内容都被正确标记并且样式看起来我们喜欢的方式,现在我们可以考虑添加一些交互行为。这就是 JavaScript 和 jQuery 起作用的地方。这一层包括动画、特效、AJAX 等等。

设计师,见识 JavaScript

JavaScript 是一种功能强大且复杂的语言 —— 你可以与之一起工作 10 年,仍然有更多要学习的内容。但不要让这吓倒你,你不必了解它的所有内容才能利用它所提供的内容。事实上,你只需要掌握一些基础知识。

这一节介绍了一些 JavaScript 基础和 JavaScript 语法。不要被那个开发者词语 —— 语法 吓倒。语法只是指编写语言的规则,就像我们有写英语的语法规则一样。

变量

让我们从简单的开始:

var x = 5;

这是 JavaScript 中的句子。在英语中,我们以句号或者可能是问号或感叹号结束句子。在 JavaScript 中,我们以分号结束我们的句子。

在这个句子中,我们正在创建一个变量,x。变量只是一个容器,用来保存东西。在这种情况下,x保存的是数字5

我们可以用 JavaScript 这样做数学:

var x = 5;
var y = 2;
var z = x + y;

就像代数一样,我们的变量z现在为我们保存了数字7的值。

但变量可以保存除了数字之外的其他东西。例如:

var text = 'A short phrase';

在这里,我们命名了我们的变量text,它为我们保存了一些字母字符。这叫做字符串。字符串是一组字母数字字符。

对象

对于 JavaScript 新手来说,对象可能是最难理解的东西,但那往往是因为我们想得太多,坚信它必须比实际更复杂。

一个对象就像它听起来的那样 —— 一个东西,任何东西。就像汽车、狗或咖啡壶都是对象。

对象具有属性和方法。属性是对象的特征。例如 — 一只狗可以高或矮,有尖耳或垂耳,是棕色或黑色,或白色。所有这些都是一只狗的属性。方法是对象可以做的事情。例如一只狗可以跑、吠、走路和吃东西。

让我们以我的狗,马格达莱纳·冯·巴尔金顿,为例,看看我们如何在 JavaScript 中处理对象、属性和方法:

var dog = Magdelena von Barkington;

这里我创建了一个变量dog,我将其用作一个容器来容纳我的狗,主要是因为我不想每次在代码中提及她时都要输入她的全名。现在假设我想要获取我的狗的颜色:

var color = dog.color;

我创建了一个名为color的容器,我用它来容纳我的狗的颜色属性 — color现在等于我的狗的颜色。

现在,我训练过我的狗,我想让她翻滚。这是我用 JavaScript 告诉她翻滚的方法:

dog.rollOver();

rollOver是一个方法 —— 我的狗能做的事情。在我的狗翻滚后,我可能想用零食奖励她。这是我用 JavaScript 让我的狗吃零食的方法:

dog.eat('bacon');

等等,这里发生了什么? 让我们一步一步来看。我们有 dog,我们知道它是一个容器,里面装着我的狗,马格达莱纳·冯·巴尔金顿。我们有eat方法,我们知道这是我的狗能做的事情。但是我的狗不能只是吃 —— 她必须吃某物。我们用括号来表示她在吃什么。在这种情况下,我的幸运狗在吃培根。在 JavaScript 里,我们会说我们正在将培根传递给狗的eat方法。

所以你看,对象并不那么难 — 它们只是事物。属性就像形容词 — 它们描述对象的特征或特性。方法就像动词 — 它们描述对象可以做的动作。

函数

函数是一小段可重复使用的代码,告诉 JavaScript 做某事。例如:

function saySomething() {
alert('Something!');
}

该函数告诉 JavaScript 弹出一个显示Something!的警告框。我们总是用单词function开始一个函数,然后命名我们的函数。接着是一对括号和一对花括号。指令行写在花括号里。

现在,我的saySomething函数在被调用之前实际上不会做任何事情,所以我需要添加一行代码来调用我的函数:

function saySomething() {
alert('Something!');
}
saySomething();

提示

下载示例代码

你可以从你在 www.PacktPub.com 上购买的所有 Packt 书籍的帐户中下载示例代码文件。如果你在其他地方购买了这本书,你可以访问 www.PacktPub.com/support 并注册,让文件直接通过电子邮件发送给你。

也许你会想知道那些括号是干什么的。还记得我们是如何通过将它们包含在括号中将东西传递给一个方法的吗?

dog.eat('bacon');

在这种情况下,我们通过bacon来说明狗正在吃什么。对于函数,我们也可以做类似的事情。事实上,方法实际上就是函数 —— 它们只是专门用于描述对象可以做什么的函数。让我们看看如何修改我们的saySomething函数,以便我们可以向其传递文本:

function saySomething(text) {
alert(text);
}
saySomething('Hello there!');

在这种情况下,当我编写saySomething函数时,我只是留下了一个通用的容器。这被称为参数 —— 我们会说saySomething函数接受一个文本参数,因为我将我的参数称为text。我选择了text这个名字,因为它是对我们传入的内容的一个简短而方便的描述。我们可以向这个函数传递任何文本片段,所以text是一个合适的名字。你可以给你的参数起任何名字 —— 但是如果在选择参数名称时应用一些常识规则,你的代码将更容易阅读和理解。参数行为非常像变量 —— 它只是一个东西的容器。

下载 jQuery 并设置

我们准备将 jQuery 的魔力引入项目中,但首先我们需要下载它并弄清如何将它附加到一个 HTML 页面上。在这里,我们将逐步了解如何启动一个示例 HTML 文件,以及我们需要处理一个示例项目设置所需的所有关联文件和文件夹。完成后,你可以将其用作本书中所有未来练习的模板。

行动时间 —— 下载并附加 jQuery

之前,我描述了 HTML 文档的三个层次 —— 内容、展示和行为。让我们看看如何为这三个层次设置我们的文件:

  1. 首先,让我们在你的硬盘上创建一个文件夹,用来保存你在本书中学习过程中的所有工作。在你的硬盘上找一个合适的位置,创建一个名为jQueryForDesigners的文件夹。

  2. 在文件夹内创建一个名为styles的文件夹。我们将使用这个文件夹来保存我们创建的任何 CSS。在styles文件夹内,创建一个名为styles.css的空 CSS 文件。

    样式代表着我们的展示层。我们将所有的样式保存在这个文件中以保持它们的分离。同样,创建一个名为images的文件夹来保存我们将要使用的任何图片。

  3. 接下来,创建一个名为scripts的文件夹来保存我们的 JavaScript 和 jQuery 代码。在scripts文件夹内,创建一个名为scripts.js的空 JavaScript 文件。

    这里编写的 JavaScript 代表我们的行为层。我们将所有的 JavaScript 都放在这个文件中,以使其与其他层分开。

  4. 现在,在jQueryForDesigners文件夹中,创建一个非常基本的新 HTML 页面,如下所示:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Practice Page</title>
    </head>
    <body>
    <!-- Our content will go here -->
    </body>
    </html>
    
    

    将该文件保存为index.html。HTML 文件是我们的内容层,可以说是最重要的层;因为这很可能是网站访问者访问我们网站的原因。

  5. 接下来,我们将把我们制作的 CSS 和 JavaScript 文件附加到我们的 HTML 页面上。在头部部分,添加一行来包含 CSS 文件:

    <head>
    <title>Practice Page</title>
    <link rel="stylesheet" href="styles/styles.css"/>
    </head>
    
    

    然后转到 HTML 文件的底部,在闭合的</body>标签之前,包含 JavaScript 文件:

    <script src="img/scripts.js"></scripts>
    </body>
    </html>
    
    

    由于这些文件只是空占位符,将它们附加到你的 HTML 页面上不会产生任何效果。但现在当我们准备进行练习时,我们有一个方便的地方来编写我们的 CSS 和 JavaScript。

    注意

    注意,自闭合<link>元素是完全可以的,但是<script>元素总是需要一个单独的闭合</script>标签。没有它,你的 JavaScript 将无法工作。

    • 到目前为止,我的文件夹看起来是这样的:

    操作时间 — 下载并附加 jQuery

  6. 现在我们要在我们的页面中包含 jQuery。前往 jquery.com,点击Download(jQuery)按钮:操作时间 — 下载并附加 jQuery

    你会注意到选择你的压缩级别下有两个选项。你总是要勾选生产复选框。这是一个准备在网站上使用的版本。开发版本是为有经验的 JavaScript 开发人员准备的,他们想要编辑 jQuery 库的源代码。

  7. 点击下载按钮会在你的浏览器窗口中打开生产 jQuery 文件,看起来有点吓人,如下所示:操作时间 — 下载并附加 jQuery

  8. 不用担心,你不必阅读它,你绝对不必理解它。只需转到浏览器的文件菜单,选择另存为...。或右键单击页面,选择另存为,然后将文件保存到我们创建的scripts文件夹中。默认情况下,脚本文件名中会包含版本号。我将继续将文件重命名为jquery.js,以保持简单。

  9. 现在我们只需在我们的页面中包含我们的 jQuery 脚本,就像我们包含我们的空 JavaScript 文件一样。转到你的练习 HTML 文件的底部,在我们之前创建的<script>标签之前添加一行来包含 jQuery:

    <script src="img/jquery.js"></script>
    <script src="img/scripts.js"></script>
    </body>
    </html>
    
    

你不会在你的 HTML 页面上注意到任何变化 — jQuery 自己不会做任何事情。它只是让它的魔法可供你使用。

使用 jQuery 的另一个选项

下载并使用自己的 jQuery 副本没有任何问题,但你还有另一个选项可用,可以帮助提高你的网站性能。那就是使用 CDN 托管的 jQuery 副本。

你可能不知道,CDN内容传递网络的简称。CDN 的前提是从离站点访问者位置物理上更近的服务器下载文件速度更快。例如,如果您在加利福尼亚州的洛杉矶,那么位于亚利桑那州凤凰城的服务器上的 jQuery 副本将比位于纽约市的服务器上的 jQuery 副本下载得更快。为了加快这个过程,CDN 在世界各地的许多不同服务器上都有相同文件的副本。每当站点访问者请求文件时,CDN 会智能地将他们的请求路由到最接近的可用服务器,有助于改善响应时间和整体站点性能。

对于本书中构建的相对简单的示例和页面来说,这并不会有太大影响,但对于公开面向网站来说,使用 CDN 托管的 jQuery 副本可以带来明显的改善。虽然有几种选择,但远非最受欢迎的是谷歌的 Ajax API CDN。您可以在code.google.com/apis/libraries/devguide.html#jquery获取有关最新版本和正确 URL 的信息。

如果您想在您的文件中使用谷歌 CDN 托管的 jQuery 版本,只需将以下代码行添加到您的 HTML 文件中即可,而不是以前用于包含 jQuery 的行:

<script src="img/jquery.min.js"></script>

不需要下载文件,也不需要保存自己的副本,您只需直接将您的<script>标签指向存储在 Google 服务器上的 jQuery 的副本即可。谷歌会负责从最近可用的服务器向您的站点访问者发送 jQuery。

不仅如此,因为谷歌的 CDN 非常受欢迎,您的站点访问者很可能已经访问过另一个也使用谷歌 CDN 托管的 jQuery 副本的站点,他们将会有

jQuery 在他们的浏览器中已缓存。这意味着您的站点访问者根本不需要下载 jQuery-它已保存在他们的浏览器中,并可以随时使用。这又如何提高性能呢?

您的第一个 jQuery 脚本

好了,现在我们对 JavaScript 的一些基本概念有了一些了解,并且知道如何设置文件和文件夹以构建一个示例练习,让我们构建我们的第一个简单的示例页面,并使用 jQuery 实现一些花里胡哨的东西。

行动时间-准备好使用 jQuery 了

  1. 就像我们在前面的练习中所做的那样设置您的文件和文件夹。在 HTML 文档的<body>内,添加一个标题和一个段落:

    <body>
    <h1>My First jQuery</h1>
    <p>Thanks to jQuery doing fancy JavaScript stuff is easy.</p>
    </body>
    
    
  2. styles文件夹中的styles.css中随意创建一些 CSS 样式-您可以随心所欲地对其进行样式化。

  3. 接下来,打开我们之前创建的空白scripts.js文件,并向文件中添加以下脚本:

    $(document).ready();
    
    

刚刚发生了什么?

让我们一次来分析这个陈述-首先是一个美元符号?真的吗?JavaScript 里面怎么会出现这个符号?

这里的$只是一个变量——就这样。它是 jQuery 函数的容器。还记得我说过我们可能使用一个变量来节省几次按键吗?jQuery 的聪明作者们提供了$变量,使我们不必每次都写出jQuery。这段代码也能完成同样的事情:

jQuery(document).ready();

除了输入时间更长之外。jQuery 使用$作为其简称,因为你很少会自己使用变量$,因为这是一个不常见的字符。使用不常见的字符可以减少在页面上使用其他 JavaScript 代码和 jQuery 库之间发生冲突的可能性。

所以,在这种情况下,我们将document传递给 jQuery 或$方法,因为我们希望将我们的 HTML 文档作为我们代码的目标选择。当我们调用 jQuery 函数时,我们得到一个 jQuery 对象。在 JavaScript 中,我们会说 jQuery 函数返回一个 jQuery 对象。jQuery 对象是 jQuery 库赋予其强大功能的核心。整个 jQuery 库存在的目的就是为了给 jQuery 对象提供许多属性和方法,使我们的生活更轻松。我们不必处理很多不同类型的对象——我们只需要处理 jQuery 对象。

jQuery 对象有一个名为ready()的方法。在这种情况下,当文档加载到浏览器中并且可以与之一起工作时,将调用 ready 方法。所以$(document).ready()的意思就是“当文档准备就绪时”。

添加一个段落

现在我们已经准备好在文档就绪时执行某些操作了,但我们要做什么呢?让我们向页面添加一个新段落。

行动时间——添加一个新段落

  1. 我们需要告诉 jQuery 在文档准备就绪时要做什么。因为我们希望发生某些事情,所以我们将传入一个函数,如下所示:

    $(document).ready(function(){
    // Our code will go here
    });
    
    

    我们将在这个函数内写明将要发生的事情。

    那行以//开头的代码呢?那是 JavaScript 中编写注释的一种方式。//告诉 JavaScript 忽略该行上的所有内容,因为它是一条注释。在 JavaScript 中添加注释是帮助自己跟踪代码发生了什么的好方法。对于可能需要处理您的代码的其他开发人员来说,这也很有帮助。即使在几个月后再次查看自己的代码,这也是很有帮助的。

  2. 接下来,我们将添加我们想要在文档准备就绪时立即发生的事情:

    $(document).ready(function(){
    $('body').append('<p>This paragraph was added with jQuery!</ p>');
    });
    
    

刚刚发生了什么?

我们的函数再次使用了 jQuery 函数:

$('body')

还记得我说过 jQuery 使用 CSS 选择器来查找东西吗?这就是我们如何使用这些 CSS 选择器的方式。在这种情况下,我想要<body>标签,所以我将'body'传递给 jQuery 函数。这会返回包装在 jQuery 对象中的<body>标签。巧妙的是,jQuery 对象有一个append()方法,让我可以向页面添加新内容:

$('body').append();

现在我所要做的就是将要添加到页面的内容传递给 append 方法。在引号中,我将传递一行 HTML 代码,我想要添加的内容:

$('body').append('<p>This paragraph was added with jQuery!</p>');

这就是全部!现在,当我在浏览器中加载我的页面时,我会看到我的标题,后面跟着两个段落 —— jQuery 会在文档加载到浏览器中时添加第二个段落:

刚刚发生了什么?

摘要

在本章中,你已经介绍了 jQuery 库,并学习了一些关于它的知识。我们讲解了一些 JavaScript 基础知识,然后学习了如何为本书中的练习设置我们的文件和文件夹。最后,我们设置了一个简单的 HTML 页面,利用 jQuery 添加了一些动态内容。现在让我们看看如何使用 jQuery 使链接更加强大。

第二章 增强链接

如今我们理所当然地使用链接,但事实上,这个不起眼的链接是改变文档并使今天的网络成为可能的事物。在此之前,将读者直接链接到另一个文档或另一个文档内的另一个位置是不可能的。

因此,你可以说超链接是互联网的支柱 —— 没有它们,搜索引擎就不可能存在,也不会有大多数网站。让我们来看看一些方法,我们可以让链接为我们提供更大的帮助。

在本章中,我们将涵盖:

  • 如何在新窗口打开链接

  • 如何向链接添加图标以识别我们正在链接到的文档类型

  • 如何将链接列表转换为简单的选项卡

在新窗口打开链接

尽管在新窗口打开链接是很常见的,但这种做法本身有些争议。有些人认为网站访问者应该自己决定是否要在新窗口打开链接,而且许多浏览器都让他们轻松实现这一点。一些人认为在新窗口打开链接会破坏返回按钮的预期行为,应该避免这样做。还有一些人认为,不在新窗口打开链接会让网站访问者感到困惑和失落,当他们突然发现自己在一个不同的网站上时。

无论你对这个问题持何种观点,客户通常都会提出这样的要求,而且这种做法可能不会很快消失,所以了解处理这种功能的选择是很重要的。我假设你已经意识到了在新窗口打开链接的问题,并已经认真权衡了所有选项,并向客户提出了一个知情的论点。

为什么不直接使用target属性呢?

你可能知道,HTML 提供了一个target属性,可以与链接一起使用,用于指定链接应该在哪里打开。例如,下面的代码:

<a href="http://packtpub.com" target="_new">Link</a>

将创建一个链接,它将尽力在新窗口或新选项卡中打开,具体取决于用户在其浏览器中设置的偏好。

开发网页标准(如 HTML)的机构 W3C 已经废弃了target属性的严格文档类型的使用,但已经将该标签重新引入了 HTML5 规范。但是,target属性旨在与框架一起使用,以控制如何将新页面加载到框架和 iframe 中。它并不是用来打开一个不使用框架的页面中的链接的,因此严格来说,为此目的使用它是不正确的。

相反,我们可以使用一点 JavaScript 来创建我们想要的行为,而不使用无效或已弃用的代码。让我们来看看如何做到这一点。

行动时间 —— 在新窗口打开链接

  1. 我们将从我们在第一章中创建的基本 HTML 文件和相关文件夹开始。在 HTML 文档的<body>中,我们将添加一些链接,如下所示:

    <h1>Opening Links in a New Window</h1>
    <p>This link will open in a new window: <a href ="http://packtpub.com">New Window!</a></p>
    <p>This link will not: <a href ="http://packtpub.com">Same Window!</a></p>
    
    

    这只是一个标题和两个简单的段落,每个段落都有一个链接——一个应该在新窗口中打开,另一个不应该。

  2. 我们需要一种方法来选择应该在新窗口中打开的链接。这与我们如果想要用 CSS 对其中一个链接进行不同样式处理时的情况类似。

    如果我们使用 CSS,我们可以为链接分配一个ID或一个类。ID会相当受限,因为ID必须在页面上是唯一的——它只适用于这个特定的链接。class将允许我们样式化任何在新窗口中打开的链接,所以这就是我们要使用的。如下所示,为应该在新窗口中打开的链接添加一个class

    <a href="http://packtpub.com" class="new-window">New Window!</a>
    
    
  3. 现在我们可以使用这个类名来进行 CSS 样式设置,并使用 jQuery 使链接在新窗口中打开。为这个链接添加一个图标是个好主意,你可以在链接的左侧或右侧添加一些填充,然后为链接添加一个背景图像。打开你的styles文件夹中的空styles.css文件,并添加以下 CSS:

    a.new-window {
    padding-right: 18px;
    background: url('../images/new-window-icon.png') 100% 50% no-repeat;
    
    
  4. 接下来,我们将打开我们的scripts文件夹中的scripts.js文件,并在我们的文档准备好声明之外开始编写我们的函数来获取我们的new-window链接并使它们在新窗口中打开。首先声明一个新函数:

    $(document).ready(function(){
    });
    function externalLinks() {
    }
    
    

    这里我们创建了一个新函数,并将其命名为externalLinks,因为这是一个合理的名称,用于在新窗口中打开链接。为 JavaScript 函数和变量命名为能帮助你记住它们的功能是非常有帮助的。

  5. 接下来,我们将使用 jQuery 选择所有具有new-window类的链接。我们将利用 jQuery 的 CSS 选择器来选择这些链接,就像我们在用 CSS 对它们进行样式设置时一样。

    function externalLinks() {
    $('a.new-window'); 
    }
    
    
  6. 我们使用了$快捷方式调用 jQuery 函数,并向函数传递了 CSS 选择器。重要的是要记住将 CSS 选择器用单引号或双引号括起来。我们不希望链接在用户点击之前就打开新窗口,因此我们的下一步是告诉链接在被点击时运行一个函数。jQuery 使这变得非常容易。我们可以使用 jQuery 提供的bind()方法将一个函数绑定到链接上,当链接被点击时将调用该函数。代码如下所示:

    function externalLinks() {
    $('a.new-window').bind('click', function() {
    });
    }
    
    

    这段代码将一个函数绑定到我们的链接上——当我们的链接被点击时,我们在这个新函数内编写的任何代码都将被调用。但到目前为止,我们的函数是空的,实际上什么也没做。

  7. 接下来我们需要做的是获取链接将我们发送到的位置:

    function externalLinks() {
    $('a.new-window').bind('click', function() {
    var location = $(this).attr('href');
    });
    }
    
    

    让我们逐一检查这一行新代码。首先,我们声明了一个名为location的新变量。你记得吧,变量只是一个容器。所以我们有了一个新的空容器,现在让我们看看我们放了什么进我们的容器。

    $(this)是 jQuery 引用我们当前正在处理的 jQuery 对象的方式。在这种情况下,我们选择所有具有new-window类的链接,并且我们已经附加了该函数,以便在站点访客点击链接时调用它。当站点访客点击链接时,我们希望检查被点击的链接以获取链接要前往的位置。引用当前链接的一个简单快捷的方式是使用$(this)

    接下来我们使用attr()方法来获取链接的属性。链接要前往的位置包含在href属性中,因此我们将href传递给attr()方法。

    因此,我们命名为location的容器现在包含了链接指向的 URL,或者在这种特殊情况下,packtpub.com.

  8. 现在我们知道我们想要去哪里了,我们只需要在新窗口中打开那个位置。在 JavaScript 中打开一个新窗口是简单直接的:

    function externalLinks() {
    $('a.new-window').bind('click', function() {
    var location = $(this).attr('href');
    window.open(location);
    });
    }
    
    

    window是 JavaScript 中的一个全局对象,始终可供我们使用。window 对象有一个open()方法,我们只需将位置传递给该方法,以便浏览器知道在新窗口中打开的位置是什么。

  9. 现在,如果你在浏览器中打开这个 HTML 页面并尝试点击链接,你可能会失望地发现我们的链接没有在新窗口中打开。就像我们的 JavaScript 根本就不在页面上一样。我们写了一个非常好的函数,但它不起作用。那是因为函数在我们告诉它们之前不会做任何事情。在 JavaScript 中告诉一个函数做它的事情的方式是'调用该函数'。

    我们希望这个函数在页面在浏览器窗口加载时立即启动,找到所有具有类new-window的链接,并将我们的新窗口函数绑定到它们上。这样,我们的应该在新窗口中打开的链接将在我们的站点访客点击其中一个链接时准备好打开一个新窗口。

    我们只需在我们的文档准备好的语句中添加一行来调用我们的函数:

    $(document).ready(function(){
    externalLinks();
    });
    function externalLinks() {
    $('a.new-window').bind('click', function() {
    var location = $(this).attr('href');
    window.open(location);
    });
    }
    
    

    这段新代码将在页面在浏览器中加载时立即调用我们的externalLinks函数。

  10. 只剩下一件事要做了。现在,如果你在浏览器中加载页面并点击链接,你会发现链接确实会在新窗口中打开,但它也会在当前窗口中打开——所以我们最终会在两个不同的窗口中加载我们的新页面。这不是我们想要的结果。我们需要做的是取消链接的默认行为——我们已经处理了在新窗口中打开位置的事情,所以现在我们需要告诉浏览器,在站点访客点击链接时不需要做任何事情。所以让我们给我们的函数添加一个参数和一行代码来取消默认链接行为。

    function externalLinks() {
    $('a.new-window').bind('click', function(e) {
    var location = $(this).attr('href');
    window.open(location);
    e.preventDefault();
    });
    }
    
    

    你会注意到我们附加到链接点击动作的函数现在括号里有一个 e。这是我们传递给这个函数的一个参数。在这种情况下,e 代表链接的点击事件。

    我们在函数中添加的代码行是:

    e.preventDefault();
    
    

    这告诉浏览器停止链接的默认行为。如果你在浏览器中重新加载页面并点击链接,你会发现它会在新窗口中正确地打开目标页面,并且不再在当前窗口中打开链接:

    执行动作的时间——在新窗口中打开链接

  11. 如果页面上有第二个应该在新窗口打开的链接,你认为会发生什么?让我们回到文档的<body>部分,添加一个应该在新窗口打开的第二个链接。在其他链接之后,添加一个新的段落和链接到一个新页面:

    <p>This paragraph will open in a new window too: <a href="http://nataliemac.com" class="new-window">New Window!</a></p>
    
    

    确保将new-window类添加到你的链接中。

现在,当你在浏览器中刷新页面时,新链接会出现在页面上。尝试点击它,你会发现它也会像其他new-window链接一样在新窗口中打开。

刚刚发生了什么?

我们给那些希望在新窗口打开的链接添加了一个 CSS 类名。现在,我们在页面上创建的任何带有new-window类的链接都会在新窗口中打开,但是当有多个链接时,JavaScript 怎么知道要在新窗口中打开哪个页面呢?

答案就在我们的externalLinks函数中。我们选择了所有带有new-window类的链接,并绑定了一个函数,当这些链接被点击时触发。在这个函数内部,我们捕获了链接的位置。这个函数只有在链接被点击时才会运行。在那之前,它只是在场边等待行动。当一个带有new-window类的链接被点击时,我们的函数开始工作,捕获了那个特定链接的位置,并打开了一个指向该链接位置的新窗口。

为链接添加图标

向链接添加图标是向您的站点访客传达链接类型的最简单方法之一。您可能对站点的不同部分有不同的图标,或者您可能希望向站点访客提供一些可下载的文件 —— 例如,您编写的 PDF 或电子书,您进行的演示文稿的幻灯片,或者您创建的一些股票图标或摄影作品。向这些类型的链接添加图标可以帮助向您的站点访客提供视觉线索,以便他们知道单击链接时会发生什么。让我们看看我们如何使用 jQuery 为不同类型的链接添加适当的图标。

这是我们向链接添加图标后页面的示例:

向链接添加图标

行动时间 —— 创建链接列表

  1. 我们将从我们创建的基本 HTML 文件和相关文件夹开始,就像我们在第一章中创建的那样,设计师,遇见 jQuery。我们将向 HTML 文档的<body>添加一系列链接列表,链接到几种不同类型的可下载文件:

    <h1>Adding Icons to Links</h1>
    <p>Here's a list of downloadable files:</p>
    <ul>
    <li><a href="http://presentation.ppt">Presentation slides</a></li>
    <li><a href="video.mp4">Video of presentation</a></li>
    <li><a href="notes.pdf">Notes for presentation</a></li>
    <li><a href="http://icons.gif">Icon sprite</a></li>
    </ul>
    
    

    当我们在浏览器中查看此列表时,我们将看到一个链接的项目列表 —— 没有视觉指示告诉用户每个链接背后是什么类型的文件 —— 用户必须根据链接的文本猜测。让我们获取所有链接并根据链接指向的文件类型为每个链接添加适当的类名。为此,我们将使用 jQuery 的属性选择器。

  2. 接下来,我们将准备好将 JavaScript 添加到我们的页面中。打开scripts文件夹中的scripts.js文件。

    让我们弄清楚如何区分一种类型的链接与另一种类型的链接。<a>链接具有href属性。这个href属性告诉我们链接将带我们去哪个页面或文件的 URL,但它也给了我们选择具有不同属性值的链接所需的信息。让我们看看 jQuery 属性选择器的工作原理:

    $('a')
    
    

    这将选择页面上的所有链接。如果我们只想获取具有href属性的<a>标签,我们可以修改我们的选择器如下:

    $('a[href]')
    
    

    我们可以再进一步,并仅获取属性等于特定值的链接:

    $('a[href="video.mp4"]')
    
    

    这个选择器只会选择链接到video.mp4文件的链接。请注意这里单引号和双引号的嵌套方式 —— 我可以使用单引号或双引号来包装我的选择器,但是如果我需要引用选择器内的内容,我必须小心选择另一种类型的引号。

    我们想要为这些链接中的每一个添加一个类名,以便我们可以使用 CSS 为它们添加我们的图标作为背景图像进行样式设置。为此,我们将使用 jQuery 对象的.addClass()方法。根据我们迄今学到的知识,我们可以在我们的文档准备就绪的语句中做类似以下的事情:

    $(document).ready(function(){
    $('a[href ="http://presentation.ppt"]').addClass('presentation');
    $('a[href="video.mp4"]').addClass('video');
    $('a[href="notes.pdf"]').addClass('pdf');
    $('a[href="http://icons.gif"]').addClass('image');
    });
    
    

    ...但这样并不是很灵活。如果我们想要添加第二个视频或另一个 PDF 文件怎么办?我们将不得不调整我们的 jQuery 来匹配。相反,让我们通过简单地查看链接的 href 属性的文件扩展名来使我们的链接更加灵活。jQuery 将允许我们检查属性是否以某些字符开头,以某些字符结尾或包含某些字符。您可以在 jQuery 文档中获取可能的属性选择器的完整列表 api.jquery.com/category/selectors/.

    要检查属性是否以某些字符开头,请使用 ^= 如下所示:

    $('a[href^="video"]')
    
    

    要检查属性是否在名称中任意位置包含某些字符,请使用 *= 如下所示:

    $('a[href*="deo"]')
    
    

    在这种情况下,文件扩展名始终是链接的最后一部分,因此我们将使用以属性选择器结尾的方式,该方式使用 $= 如下所示:

    $(document).ready(function(){
    $('a[href$="ppt"]').addClass('presentation');
    $('a[href$="mp4"]').addClass('video');
    $('a[href$="pdf"]').addClass('pdf');
    $('a[href$="gif"]').addClass('image');
    });
    
    
  3. 现在,例如,任何我们添加的具有 .pdf 扩展名的链接将自动被赋予 pdf 类。如果您在浏览器中刷新页面,此时您不会看到页面上的任何区别,但是如果您使用浏览器检查工具(例如内置在 Chrome 和 WebKit 中的工具或 Firefox 的 Firebug)检查 DOM (Document Object Model),您将看到链接已被赋予类名。剩下的就是编写 CSS 来包含图标了。打开 styles 文件夹中的 styles.css 文件,并添加一些代码行,如下所示:

    a {
    background: 0 50% no-repeat;
    padding-left: 20px;
    }
    a.presentation {
    background-image: url(../images/presentation.gif);
    }
    a.video {
    background-image: url(../images/video.gif);
    }
    a.pdf {
    background-image: url(../images/pdf.gif);
    }
    a.image {
    background-image: url(../images/image.gif);
    }
    
    

    您必须确保将图标图像放在 images 文件夹内。您可以使用本章示例代码中包含的图标图像,也可以创建您自己的图标。

    现在,如果您在浏览器中刷新页面,您将看到每个链接显示适当的图标。如果您向页面添加了这四种文件类型的新链接,它们也将具有相应的图标。我们为链接添加图标创建了一个灵活且简单的解决方案。

    行动时间 — 创建链接列表

刚刚发生了什么?

我们根据 href 属性中的文件扩展名选择了页面上的所有链接,并使用 jQuery 添加了适当的类名。然后,我们在 CSS 中使用这些类名为每个链接类型添加了图标,并应用了一些 CSS 样式。没有启用 JavaScript 的网站访问者仍然可以单击链接并下载相关文件。他们只会错过指示每个链接后面文件类型的图标。

现在您可以看到 jQuery 和 CSS 如何共同工作以向您的页面添加新功能。jQuery 可以修改元素的类名,然后可以使用 CSS 根据其类名样式化这些元素。

简单的标签页

如果我们有大量信息需要呈现,但这些信息可能对所有网站访问者都不相关,我们可以通过隐藏选定的信息位来压缩信息占用的空间,直到网站访问者请求它。制作所有信息可用但隐藏直到请求的最常见方法之一是选项卡。选项卡反映了现实世界中的一个例子,即带标签的笔记本或文件柜中的标记文件夹,并且易于网站访问者理解。信不信由你,它们还可以使用 jQuery 轻松实现。

这是我们创建选项卡后页面的大致样子:

简单选项卡

行动时间 —— 创建简单的选项卡

  1. 我们将从我们的基本 HTML 文件和相关文件夹开始,就像我们在 第一章中创建的那样,设计师,遇见 jQuery。在<body>标签内,我们将从设置一个简单的示例开始,即使对于禁用 JavaScript 的用户也可以使用:我们将在页面顶部放置一系列指向页面不同区域的锚链接,然后将每个内容部分包装在一个带有iddiv中,如下所示:

    <h1>Simple Tabs Product</h1>
    <p>You should buy this, it's great!</p>
    <ul>
    <li><a href="#description">Description</a></li>
    <li><a href="#photos">Photos</a></li>
    <li><a href="#details">Details</a></li>
    <li><a href="#reviews">Customer Reviews</a></li>
    <li><a href="#related">Related Items</a></li>
    </ul>
    <div id="description">
    <h2>Overview</h2>
    <p>This section contains a basic overview of our product.</p>
    </div>
    <div id="photos">
    <h2>Photos</h2>
    <p>This section contains additional photos of our product.</p>
    </div>
    <div id="details">
    <h2>Details</h2>
    <p>This is where we list out all the details of our product—size, weight, color, materials, etc.</p>
    </div>
    <div id="reviews">
    <h2>Customer Reviews</h2>
    <p>Here's where we would list all of the glowing reviews our customers had written</p>
    </div>
    <div id="related">
    <h2>Related Items</h2>
    <p>And here we would list out other super items that our customers might also like to buy.</p>
    </div>
    
    

    如果我们在浏览器中查看此 HTML,我们将看到页面顶部有一个链接列表,点击后页面会跳转到相应部分,这样网站访问者就可以轻松找到每个部分,而不需要自己滚动。我们基本上为我们的页面创建了一个可点击的目录。

  2. 现在我们想要为启用 JavaScript 的网站访问者增强此功能。我们将首先为包含我们目录的<ul>添加一个id,并为包含我们内容部分的每个<div>添加一个类名 —— 这将使我们更容易使用 jQuery 选择我们想要的页面部分,并且也将使我们更容易使用 CSS 样式化我们的选项卡。

    <ul id="tabs">
    <li><a href="#description">Description</a></li>
    <li><a href="#photos">Photos</a></li>
    <li><a href="#details">Details</a></li>
    <li><a href="#reviews">Customer Reviews</a></li>
    <li><a href="#related">Related Items</a></li>
    </ul>
    <div id="description" class="tab-section">
    <h2>Overview</h2>
    <p>This section contains a basic overview of our product.</p>
    </div>
    <div id="photos" class="tab-section">
    <h2>Photos</h2>
    <p>This section contains additional photos of our product.</p>
    </div>
    <div id="details" class="tab-section">
    <h2>Details</h2>
    <p>This is where we list out all the details of our product—size, weight, color, materials, etc.</p>
    </div>
    <div id="reviews" class="tab-section">
    <h2>Customer Reviews</h2>
    <p>Here's where we would list all of the glowing reviews our customers had written</p>
    </div>
    <div id="related" class="tab-section">
    <h2>Related Items</h2>
    <p>And here we would list out other super items that our customers might also like to buy.</p>
    </div>
    
    
  3. 接下来,我们将使用 jQuery 隐藏所有我们的tab-sections。打开你的scripts文件夹中的scripts.js文件,在文档ready语句内选择tab-sections并隐藏它们:

    $(document).ready(function(){
    $('.tab-section').hide();
    });
    
    

    现在当我们加载页面时,我们只会看到我们的目录。

  4. 接下来,当我们的选项卡之一被点击时,我们需要显示相应的部分。我们将从将函数绑定到目录内链接的单击事件开始 —— 就像我们在打开新窗口时所做的那样:

    $(document).ready(function(){
    $('.tab-section').hide();
    $('#tabs a').bind('click', function(e){
    e.preventDefault;
    });
    });
    
    

    通过这一小段代码,我们选择了带有 id 为#tabs<ul>内的所有链接,并将一个函数绑定到单击链接上。到目前为止,这个函数所做的一切都是取消点击 —— 如果你在浏览器中加载页面,你会发现点击链接不会做任何事情 —— 页面不再跳转到相关部分。

  5. 接下来,我们想要选择适当的部分并显示它。为此,我们将使用哈希 —— 或包含#符号的href属性的部分。

    $('#tabs a').bind('click', function(e){
    $(this.hash).show();
    e.preventDefault;
    });
    
    

    当我把this.hash传递给 jQuery 函数时,我正在处理的this是刚刚点击的链接,this.hash是从#符号开始直到结尾的 href 属性的值。例如,如果我点击概览标签,把this.hash传递给 jQuery 函数就等同于写下以下内容:

    $('#overview')
    
    

    当然,这是以一种更加灵活的方式完成的 —— 它将适用于页面任何与之链接的标签。例如,如果我想用运输信息标签替换客户评论标签,我就不需要更新我的 JavaScript 代码,只需要更新 HTML 标记本身 —— JavaScript 足够灵活,可以适应变化。

  6. 现在当我点击目录链接中的一个时,它将显示给我相应的部分,但如果我不断点击链接,部分就会不断显示,点击所有链接后,所有部分都可见,这不是我们想要的。我们需要隐藏可见的部分,只显示我们想要的部分。让我们在代码中添加一行来选择可见的tab-section并在显示新部分之前隐藏它:

    $('#tabs a').bind('click', function(e){
    $('.tab-section:visible').hide();
    $(this.hash).show();
    e.preventDefault;
    });
    
    

    你可能熟悉 CSS 中的伪类选择器 —— 它们经常用于选择链接的 hover、visited 和 active 状态(a:hover, a:visiteda:active)。jQuery 为我们提供了一些额外的伪类选择器,这里有用于按钮、空元素、禁用表单字段、复选框等的伪类选择器。你可以在 jQuery 文档中查看 jQuery 的所有可用选择器 http://api.jquery.com/category/selectors/。这里,我们使用:visible伪类选择器来选择当前可见的.tab-section。一旦我们选择了可见的.tab-section,我们就把它隐藏起来,然后找到正确的tab-section并显示它。

  7. 现在我们需要一些 CSS 来使我们的标签样式看起来像内容的分栏部分。打开你的styles文件夹中的styles.css文件,添加一些 CSS 样式如下。随意定制它们以适应你自己的口味。

    #tabs {
    overflow: hidden;
    zoom: 1;
    }
    #tabs li {
    display: block;
    list-style: none;
    margin: 0;
    padding: 0;
    float: left;
    }
    #tabs li a {
    display: block;
    padding: 2px 5px;
    border: 2px solid #ccc;
    border-bottom: 0 none;
    text-align: center;
    }
    .tab-section {
    padding: 10px;
    border: 2px solid #ccc;
    }
    
    
  8. 现在如果你在浏览器中加载这个页面,你会发现有一点还不够 —— 我们应该突出显示当前选定的标签,以便明确显示哪一个被选定。我们可以通过为当前标签添加一个 CSS 类来实现这一点。回到你的scripts.js文件,添加一段代码为当前标签添加一个类,并从任何非当前标签中移除类如下:

    $('#tabs a').bind('click', function(e){
    $('#tabs a.current').removeClass('current');
    $('.tab-section:visible').hide();
    $(this.hash).show();
    $(this).addClass('current');
    e.preventDefault;
    });
    
    

    首先,我们会找到具有current类的选项卡,并删除那个类。然后我们将获取刚刚点击的选项卡,并在它上面添加current类。这样,我们确保每次只有一个选项卡被标记为当前选项卡。

  9. 接下来,在我们的 CSS 中为我们的新类添加一些样式。打开styles.css,添加一些代码以区分当前选定的选项卡。同样,随意定制这种风格以适应你自己的口味:

    #tabs li a.current {
    background: #fff;
    color: #000;
    }
    
    
  10. 现在我们的选项卡已经按我们的期望工作了,剩下的唯一事情就是在页面首次加载时使第一个选项卡处于活动状态,并显示第一个内容部分,而不是将它们全部隐藏。我们已经编写了执行此操作的函数,现在我们只需为我们的第一个选项卡调用它:

    $('#tabs a').bind('click', function(e){
    $('#tabs a.current').removeClass('current');
    $('.tab-section:visible').hide();
    $(this.hash).show();
    $(this).addClass('current');
    e.preventDefault;
    }).filter(':first').click();
    
    

    jQuery 对象的 filter() 方法将允许我们过滤先前选择的一组元素 —— 在本例中,我们处理的是具有 id #tabs<ul> 中的所有 <a> 标签。我们将一个点击函数绑定到所有这些链接,然后我们将使用 :first 伪类过滤出第一个链接 —— 在 jQuery 中为我们提供了这个功能,并告诉 jQuery 为我们点击第一个选项卡,这将运行我们的函数,将 current 类添加到第一个链接,并显示第一个 .tab-section —— 就像我们加载页面时期望的那样。

    行动时间 —— 创建简单选项卡

刚才发生了什么?

我们使用 jQuery 设置了一组简单的选项卡。对于禁用 JavaScript 的网站访问者,选项卡将像文档顶部的目录一样运行,当点击它们时,它们会跳转到各个内容部分。然而,对于启用 JavaScript 的网站访问者,内容部分将完全隐藏,直到需要。点击每个选项卡会显示与该选项卡相关联的内容。这是在用户界面中节省空间的绝佳方式 —— 在一个小空间中按需提供所有内容。

我们使用 JavaScript 隐藏选项卡内容,而不是使用 CSS,以确保没有启用 JavaScript 的用户仍然能够访问我们的所有内容。

总结

在本章中,您学习了如何使用基本链接 —— 互联网的支柱 —— 并增强它们以添加一些新的行为和功能。您学习了如何使链接在新窗口中打开,根据链接的文件类型添加图标以及如何设置基本的选项卡界面。这些都是网站的非常常见的要求,当您学习更多关于 jQuery 和 JavaScript 的知识时,这些将作为您的良好基石。

第三章:打造更好的常见问题解答页面

自互联网诞生以来,常见问题解答页面一直是各种类型的网站的主要页面。它被用作营销页面,试图减少对客户服务部门的电话或电子邮件数量,并且作为站点访问者了解与之交易的公司或组织,或者他们感兴趣购买的产品或服务的有用工具。

虽然我们将为此示例构建一个常见问题解答页面,但此展开和折叠技术在许多不同情况下都很有用 — 事件列表与事件详情、员工或成员列表与简介、产品列表与详情 — 任何情况下都应该使站点访问者能够快速浏览项目列表,但在他们找到所需内容时应该能够立即轻松地根据需求获取更多信息。

在本章中,我们将学习:

  • 如何使用 jQuery 遍历 HTML 文档

  • 如何显示和隐藏元素

  • 如何使用简单的 jQuery 动画

  • 如何轻松切换元素的类名

常见问题解答页面标记

我们将从特别关注我们如何标记常见问题解答列表开始。与大多数涉及 Web 开发的事情一样,没有一种正确的方法,所以不要将这种方法视为唯一正确的方法。任何语义上合理且便于使用 CSS 和 JavaScript 增强列表的标记都是完全可以接受的。

行动时间 — 设置 HTML

  1. 我们将从我们的示例 HTML 文件和关联的文件和文件夹开始,就像我们在第一章中设置的那样,设计师,遇见 jQuery。在这种情况下,我们的 HTML 将是一个包含在<dt>标签中的问题的定义列表,而答案则包含在<dd>标签中。默认情况下,大多数浏览器会缩进<dd>标签,这意味着问题会悬挂在左边距中,使其易于浏览。在 HTML 文档的<body>内,按如下方式添加标题和定义列表:

    <h1>Frequently Asked Questions</h1>
    <dl>
    <dt>What is jQuery?</dt>
    <dd>
    <p>jQuery is an awesome JavaScript library</p>
    </dd>
    <dt>Why should I use jQuery?</dt> <dd>
    <p>Because it's awesome and it makes writing JavaScript faster and easier</p>
    </dd>
    <dt>Why would I want to hide the answers to my questions? </dt>
    <dd>
    <p>To make it easier to peruse the list of available questions - then you simply click to see the answer you're interested in reading.</p>
    </dd>
    <dt>What if my answers were a lot longer and more complicated than these examples?</dt>
    <dd>
    <p>The great thing about the &lt;dd&gt; element is that it's a block level element that can contain lots of other elements.</p>
    <p>That means your answer could contain:</p>
    <ul>
    <li>Unordered</li>
    <li>Lists</li>
    <li>with lots</li>
    <li>of items</li>
    <li>(or ordered lists or even another definition list)</li>
    </ul>
    <p>Or it might contain text with lots of <strong>special</strong> <em>formatting</em>.</p>
    <h2>Other things</h2>
    <p>It can even contain headings. Your answers could take up an entire screen or more all on their own - it doesn't matter since the answer will be hidden until the user wants to see it.</p>
    </dd>
    <dt>What if a user doesn't have JavaScript enabled?</dt>
    <dd>
    <p>You have two options for users with JavaScript disabled - which you choose might depend on the content of your page.</p>
    <p>You might just leave the page as it is - and make sure the &lt;dt&gt; tags are styled in a way that makes them stand out and easy to pick up when you're scanning down through the page. This would be a great solution if your answers are relatively short.</p>
    <p>If your FAQ page has long answers, it might be helpful to put a table of contents list of links to individual questions at the top of the page so users can click it to jump directly to the question and answer they're interested in. This is similar to what we did in the tabbed example, but in this case, we would use jQuery to hide the table of contents when the page loaded since users with JavaScript wouldn't need to see the table of contents.</p>
    </dd>
    </dl>
    
    
  2. 你可以通过添加一些 CSS 来调整页面的样式。以下是我的样式设置方式:行动时间 — 设置 HTML

对于禁用 JavaScript 的用户,该页面可以正常工作。问题会悬挂在左边距中,比页面上的其他文本更加粗体和深色,使其易于浏览。

刚刚发生了什么?

我们设置了一个基本的定义列表来保存我们的问题和答案。默认样式的定义列表很好地使得问题列表对于没有 JavaScript 的站点访问者易于浏览。我们可以进一步通过自定义 CSS 来增强我们的样式以使列表的风格与我们的站点匹配。

行动时间 — 在 HTML 文档中移动

  1. 我们将继续使用前一节设置的文件进行工作。打开位于您的scripts文件夹内的scripts.js文件。在文档就绪语句之后,编写一个名为dynamicFaq的新空函数:

    function dynamicFaq() {
    //our FAQ code will go here
    }
    
    
  2. 让我们思考一下我们希望此页面的行为。我们希望在页面加载时将所有问题的答案隐藏,然后当用户找到他们正在寻找的问题时,当他们点击问题时,我们希望显示相关答案。

    这意味着当页面加载时,我们首先需要隐藏所有答案。这只是简单地选择所有我们的<dd>元素并隐藏它们。在您的dynamicFaq函数内,添加一行代码以隐藏<dd>元素:

    function dynamicFaq() {
    $('dd').hide();
    }
    
    

    行动时间 - 在 HTML 文档中移动

    注意

    您可能想知道为什么我们没有使用 CSS 将<dd>标签的显示设置为none。那样会隐藏我们的答案,但会使所有人都无法访问我们的答案 - 没有启用 JavaScript 的网站访问者将无法访问页面的最重要部分 - 答案!

    这也会阻止大多数搜索引擎索引我们答案内的内容,这对于试图在搜索引擎中找到答案的人可能是有帮助的。通过使用 JavaScript 隐藏答案,我们可以确保答案将可用,除非用户启用了 JavaScript 并且能够再次显示它们。

  3. 现在,当网站访问者点击问题时,我们需要显示答案。为此,我们需要告诉 jQuery 在有人点击其中一个问题或<dt>标签时做些什么。在dynamicFaq函数内,添加一行代码以将点击函数绑定到<dt>标签:

    function dynamicFaq() {
    $('dd').hide();
    $('dt').bind('click', function(){
    //Show function will go here
    });
    }
    
    
  4. 当网站访问者点击问题时,我们希望获取该问题的答案并显示出来,因为我们的常见问题列表设置与以下代码类似:

    <dl>
    <dt>Question 1</dt>
    <dd>Answer to Question 1</dd>
    <dt>Question 2</dt>
    <dd>Answer to Question 2</dd>
    ...
    </dl>
    
    

    …我们知道答案是我们问题后的 DOM 中的下一个节点或元素。我们将从问题开始。当网站访问者点击问题时,我们可以使用 jQuery 的$(this)选择器获取当前问题。用户刚刚点击了一个问题,我们使用$(this)来表示他们刚刚点击的问题。在该新的click函数中,添加$(this)以便我们可以引用点击的问题:

    $('dt').bind('click', function(){
    $(this);
    });
    
    
  5. 现在我们已经有了刚刚点击的问题,我们需要获取下一个内容或该问题的答案,以便我们可以显示它。这在 JavaScript 中称为DOM 遍历。这只是意味着我们正在移动到文档的另一部分。

    jQuery 为我们提供了next()方法来移动到 DOM 中的下一个节点。我们将通过以下方式选择我们的答案:

    $('dt').bind('click', function(){
    $(this).next();
    });
    
    
  6. 现在我们已经从问题移动到答案。现在剩下的就是显示答案:

    $('dt').bind('click', function(){
    $(this).next().show();
    });
    
    
  7. 别忘了,我们的dynamicFaq函数在我们调用它之前什么都不会做。在您的文档就绪语句中调用dynamicFaq函数:

    $(document).ready(function(){
    dynamicFaq();
    });
    
    
  8. 现在,如果我们在浏览器中加载页面,您会发现在单击问题之前,我们所有的答案都是隐藏的。这很好也很有用,但是如果网站访问者完成阅读后可以再次隐藏答案以摆脱它,那将更好。幸运的是,这是一个常见任务,jQuery 为我们提供了很大的帮助。我们所要做的就是将我们的 .show() 方法替换为 .toggle() 方法,如下所示:

    $('dt').bind('click', function(){
    $(this).next().toggle();
    });
    
    

现在,当您在浏览器中刷新页面时,您会发现单击问题会显示答案,再次单击问题会再次隐藏答案。

刚刚发生了什么?

在页面上切换元素的显示是一个常见的 JavaScript 任务,所以 jQuery 已经内置了处理它的方法,并且使得在我们的页面上实现这个功能变得简单明了。这相当容易;只需几行代码。

点缀我们的常见问题解答页面

实际上,这么简单,我们还有大量时间来增强我们的常见问题解答页面,使其变得更好。这就是 jQuery 的威力所在 — 您不仅可以创建一个显示/隐藏的常见问题解答页面,而且还可以使其变得花哨,并且仍然能够按时完成任务。这对于给客户或老板留下深刻印象来说如何?

行动时间 — 让它变得花哨

  1. 让我们从一点 CSS 开始,将鼠标光标更改为指针,并向我们的问题添加一点悬停效果,以便向网站访问者明确表明问题是可点击的。打开位于样式文件夹中的 styles.css 文件,并添加以下 CSS 代码:

    dt {
    color: #268bd2;
    font-weight: bold;
    cursor: pointer;
    margin: 0 0 1em 0;
    }
    dt:hover {
    color: #2aa198;
    }
    
    

    这绝对有助于向网站访问者传达问题是可点击的信息。

    行动时间 — 让它变得花哨

  2. 当我们单击问题查看答案时,页面上的变化没有很好地传达给网站访问者 — 页面上的跳转有点让人不安,需要一会儿才能意识到刚刚发生了什么。如果问题能够平滑地显示出来,那将更加舒适和易于理解;网站访问者可以看到问题的出现,立即理解屏幕上刚刚发生的变化。

    jQuery 为我们提供了便利。我们只需将我们的 .toggle() 方法替换为 .slideToggle() 方法。

    $('dt').bind('click', function(){
    $(this).next().slideToggle();
    });
    
    

现在,如果您在浏览器中查看页面,您会发现点击问题时,问题会平滑地显示和隐藏。当页面发生变化时,很容易理解发生了什么,并且动画效果很不错。

刚刚发生了什么?

我们用 slideToggle() 方法替换了我们的 toggle() 方法来动画显示和隐藏答案。这使得网站访问者更容易理解页面上发生的变化。我们还添加了一些 CSS,使问题看起来像是可点击的,以向我们的网站访问者传达我们页面的能力。

我们快要完成了!

jQuery 使得动画的显示和隐藏变得如此容易,以至于我们仍然有时间进一步增强我们的 FAQ 页面。添加一些指示器来显示我们的问题已经折叠并且可以展开,以及一旦它们被打开就添加一些特殊的样式以显示它们可以再次折叠,这将是很好的。

行动时间——添加一些最后的修饰

  1. 让我们从一些简单的 CSS 开始,向我们的问题的左侧添加一个小箭头图标。返回style.css并稍微修改样式以添加一个箭头图标或您选择的图标。您可以将所选图标放在images文件夹中:

    dt {
    color: #268bd2;
    font-weight: bold;
    cursor: pointer;
    margin: 0 0 1em 0;
    padding: 0 0 0 20px;
    background: url(../images/arrow.png) 0 0 no-repeat;
    line-height: 16px;
    }
    dt:hover {
    color: #2aa198;
    background-position: 0 -32px;
    }
    
    

    我正在使用图像精灵来显示箭头。当鼠标悬停在问题上时,我将我的问题从蓝色更改为绿色,因此我在精灵中包含了蓝色和绿色的箭头,并且在文本变为绿色时使用了一些 CSS 来显示绿色箭头。这意味着只需下载一个图像,无需在鼠标悬停在我的问题上时下载新图像来显示。如果您对 CSS 图像精灵技术不熟悉,我建议您查看Chris Coyiercss-tricks.com/css-sprites/.上解释它的文章。

  2. 现在,当问题打开时,我们想要将箭头改为不同的方向。我们所要做的就是为我们的问题的打开状态使用一个新的 CSS 类,并编写关闭和打开状态的代码,以便新的箭头形状也会改变颜色。同样,我已经将这些箭头图像包含在同一个精灵中,所以我唯一需要改变的就是背景位置:

    dt.open {
    background-position: 0 -64px;
    }
    dt.open:hover {
    background-position: 0 -96px;
    }
    
    

    注意

    请确保在我们用来为<dt>标签添加样式的其他 CSS 之后添加这些新类。这样可以确保 CSS 按照我们的意图级联。

  3. 所以我们有了 CSS 来显示我们的问题是打开的,但是我们如何实际使用它呢?我们将使用 jQuery 在问题打开时向我们的问题添加类,并在关闭时删除类。

    jQuery 提供了一些很好的方法来处理 CSS 类。addClass()会将一个类添加到 jQuery 对象中,而removeClass()会删除一个类。但是,我们想要像切换问题的显示和隐藏一样切换我们的类。jQuery 也为此提供了支持。当我们点击问题时,我们希望类发生变化,因此我们将在我们每次点击<dt>时调用的dynamicFaq函数中添加一行代码:

    $('dt').bind('click', function(){
    $(this).toggleClass('open');
    $(this).next().slideToggle();
    });
    
    

    现在当您查看页面时,您将看到在<dt>标签打开时应用的打开样式,并在关闭时再次删除。但我们实际上可以将我们的代码压缩得更小一些。

  4. jQuery 最强大的功能之一被称为链式调用。当我们在一行中向next()方法添加了slideToggle()时,我们已经使用了链式调用。

    $(this).next().slideToggle();
    
    

    jQuery 中的方法可以链接在一起。您可以继续添加新的方法来进一步转换、修改或动画化一个元素。这行代码获取问题,遍历 DOM 到下一个节点,我们知道这是我们的 <dd>,然后切换那个 <dd> 的滑动动画。

    我们可以再次利用链接。我们的代码中存在一些冗余,因为我们在两行不同的代码中都以 $(this) 开头。我们可以删除额外的 $(this),并将我们的 toggleClass() 方法添加到我们已经开始的链中,如下所示:

    $(this).toggleClass('open').next().slideToggle();
    
    

    行动时间 — 添加最后的一些修饰

刚刚发生了什么?

我们创建了 CSS 样式来为我们的问题的打开和关闭状态添加样式,然后我们在我们的 JavaScript 中添加了一点代码来更改问题的 CSS 类以使用我们的新样式。jQuery 提供了几种不同的方法来更新 CSS 类,这通常是对来自站点访问者的输入做出响应时更新文档显示的一种快速简便的方法。在这种情况下,由于我们想要添加和移除一个类,所以我们使用了 toggleClass() 方法。这使我们免于自己去弄清楚是否需要添加或移除打开类。

我们还利用链接来简单地将这个新功能添加到我们现有的代码行中,使得答案的动画显示和隐藏以及我们问题的 CSS 类的更改都只需一行代码即可完成。这对于在短时间内用少量代码实现令人印象深刻的功能来说,算怎么样?

总结

在本章中,我们学习了如何设置一个基本的常见问题解答页面,该页面在站点访问者需要查看答案之前隐藏问题。由于 jQuery 让这个过程变得如此简单,我们有足够的时间来进一步增强我们的常见问题解答页面,为我们的问题的显示和隐藏添加动画效果,并利用 CSS 来为我们的问题添加特殊的打开和关闭类,以向我们的站点访问者传达我们页面的工作方式。而我们只用了几行代码就完成了所有这些工作。

接下来,我们将学习如何在我们的页面上使用自定义滚动条。

第四章:构建自定义滚动条

处理具有大量内容的页面的常见策略是隐藏一些内容,直到站点访问者希望或需要它。有许多方法可以做到这一点 —— 您可以使用选项卡、手风琴、灯箱,或者本章重点,可滚动区域。

可滚动区域易于站点访问者理解和使用,但它们经常被忽视,因为一些操作系统有难看的滚动条,这会破坏您精心调整的设计美感。浏览器几乎没有提供用于自定义滚动条外观的选项,也从未在任何 HTML 或 CSS 规范中包含官方手段。

一些设计师已经转向 Flash 来创建自定义滚动条,我相信你一定遇到过这些 Flash 滚动条的示例,往往它们笨拙且违反处理可滚动区域的常规惯例。例如,您很少能够使用鼠标的滚轮来滚动 Flash 可滚动区域。

在本章中,我们将学习:

  • 如何下载和使用 jQuery 插件,以便更多地使用 jQuery

  • 如何使用插件的内置定制选项来定制插件的工作方式

  • 如何使用 CSS 进一步定制插件

  • 如何设置自定义设计的滚动条,使其与您的站点访问者的期望一样工作

  • 如何使用 jScrollPane 插件在我们的可滚动区域之间平滑滚动到不同的内容部分

设计师,认识一下插件

我们已经谈过程序员如何一次又一次地解决相同的问题。正是这些常见的任务,jQuery 简化了我们能够用最少的代码完成这些任务。但是对于一些仅仅是有些常见的任务,比如想要漂亮的自定义滚动条,如何解决呢?

这就是 jQuery 社区变得重要的地方。jQuery 社区的开发人员能够编写代码,扩展 jQuery 的功能,简化一些常见的任务。这些代码片段称为插件,它们与 jQuery 库一起使用,使编写复杂的交互、小部件和效果就像使用 jQuery 已经内置的功能一样简单。

在官方 jQuery 网站上,您会找到数百个 jQuery 插件的库。除此之外,还有数千个来自 Web 上各个站点的插件,几乎可以完成您想要完成的任何任务。

要创建自定义滚动条,我们将使用Kelvin Luck的 jScrollPane 插件。您将学习如何在您的页面上安装插件以及如何配置 CSS 和选项,使您的滚动条看起来和工作方式符合您的要求。

选择插件

最近,jQuery 团队已经开始支持一小部分官方 jQuery 插件,你可以放心使用这些插件,因为它们具有与 jQuery 本身相同水平的专业知识、文档和支持。所有其他 jQuery 插件都是由 jQuery 社区的各个成员提供的,这些作者对其自己的插件负有文档和支持的责任。撰写和提供 jQuery 插件有点像自由竞争,遗憾的是,你会发现一大堆文档质量差、支持不够好,甚至更糟糕,编写得很差的 jQuery 插件。作为一个新手 jQuery 用户,选择插件时应该寻找哪些特征呢?

  • 插件的最新更新。频繁的更新意味着插件得到了良好的支持,作者也在保持插件随着 jQuery 和浏览器的演变而更新。

  • 彻底易懂的文档。在尝试下载和使用插件之前,请浏览插件的文档,并确保您了解如何实现插件以及如何使用插件提供给您的任何选项。

  • 浏览器支持。优秀的插件一般具有与 jQuery 库本身相同的浏览器支持。

  • 工作演示。大多数插件作者都会提供一个或多个插件的工作演示。尽可能在不同的浏览器中查看演示,以确保插件如广告所述的那样工作。

  • 评论和评分。并非所有插件都有评论和评分,但如果你能找到一些,它们可以是插件质量和可靠性的有用指标。

设置一些可滚动的 HTML

让我们看看如何设置一个包含可滚动区域的简单 HTML 页面。一旦我们完成了这个,我们将看看如何用自定义的滚动条替换默认的滚动条。

行动时间 —— 可滚动 HTML

按照以下步骤设置一个包含可滚动区域的简单 HTML 页面:

  1. 我们将从设置一个基本的 HTML 页面和相关的文件和文件夹开始,就像我们在 Chapter 1 中所做的那样,设计师,遇见 jQuery。我们需要有一个足够大的内容区域来滚动,所以我们将在 HTML 文档的正文部分添加几段文本:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Custom Scrollbars</title>
    <link rel="stylesheet" href="styles/styles.css"/>
    </head>
    <body>
    <h2>We don't want this box of content to get too long, so we'll make it scroll:</h2>
    <p>Lorem ipsum dolor sit amet...
    Include several paragraphs of lorem ipsum here
    ...mollis arcu tincidunt.</p>
    <script src="img/jquery.js"></script>
    <script src="img/scripts.js"></script>
    </body>
    </html>
    
    

    我没有包含所有内容,但我在我的页面上包含了五段长的 lorem ipsum 文本,以增加页面的长度,并为我们提供一些可滚动的内容。如果你不知道,lorem ipsum 只是一种虚拟的填充文本。你可以在lipsum.com上生成一些随机的 lorem ipsum 文本来填充你的页面。

  2. 现在,我们需要使我们的文本滚动。为了做到这一点,我要将所有那些 lorem ipsum 的段落包裹在一个div中,然后使用 CSS 在div上设置高度,将overflow设置为auto

    <h2>We don't want this box of content to get too long, so we'll make it scroll:</h2>
    <div id="scrolling">
    <p>Lorem ipsum dolor sit amet...
    Include several paragraphs of lorem ipsum here
    ...mollis arcu tincidunt.</p>
    </div>
    
    
  3. 接下来,打开你的空的styles.css文件,添加下面的 CSS 来实现我们的文本区域可以滚动:

    #scrolling {
    width:500px;
    height:300px;
    overflow:auto;
    }
    
    

    随意添加一些额外的 CSS 来自定义您的文本样式。

    现在,当我在浏览器中查看我的页面时,我会看到浏览器已经为我的文本添加了一些(丑陋的)滚动条:

    实践时间—可滚动的 HTML

添加自定义滚动条

在大多数情况下,滚动条的外观是由您的网站访问者所使用的操作系统决定的,而不是他们的浏览器。所以,无论您在 Mac 上使用 Firefox、Safari、Chrome 还是其他浏览器,您总是会看到那些标志性的闪亮蓝色滚动条。在 PC 上,无论您在 Windows 选项中设置了什么颜色方案,您总是会看到那些笨拙的方形滚动条。

实践时间—简单自定义滚动条

您会发现操作系统的默认滚动条在我们精美设计的页面中格外突兀。让我们来解决这个问题,好吗?

  1. 首先,我们要找到要使用的插件来创建自定义滚动条。前往jscrollpane.kelvinluck.com/,点击导航菜单中的下载链接:实践时间—简单自定义滚动条

    这将带您跳转到站点的下载部分,在那里您会看到 Kelvin Luck 正在使用 Github 来托管他的代码。Github 是一个社交编程中心—一种面向开发者的 Facebook—主要集中在撰写、分享和讨论代码。如今,使用 Github 来托管 jQuery 插件和其他开源代码项目变得越来越普遍,因为 Github 为开发者提供了一个简单的方式来与他人分享和合作他们的代码。

    别担心—从 Github 下载插件很简单。我会带你一步步完成。

  2. 首先,在Kelvin Luck的网站上点击 Github 链接:实践时间—简单自定义滚动条

  3. 这将带您进入 jScrollPane 项目在 Github 上的主页。在页面的右侧,您会看到一个下载按钮:实践时间—简单自定义滚动条

  4. 点击下载按钮后,会弹出模态对话框,显示项目的所有可用下载包。简单明了,只需点击下载 .zip按钮即可获取最新版本:实践时间—简单自定义滚动条

  5. ZIP 下载将自动开始。一旦完成,在 Github 完成。我告诉过你,这很简单。现在,让我们解压这个包并看看里面有什么。实践时间—简单自定义滚动条

    哇!这么多文件!我们应该怎么处理这些文件?

    看上去有点吓人和混乱,但这些文件大部分都是关于如何使用插件的示例和文档。我们只需要找到组成插件的 JavaScript 文件。我们将在script文件夹中找到它们。

    实践时间—简单自定义滚动条

  6. script文件夹内,我们将找到更多我们期望的内容。让我们弄清楚这些文件是什么。

    • demo.js是示例代码。这是凯尔文·拉克用来组合压缩文件中各种演示的内容。如果我们卡住了,看看示例可能会有用,但我们不需要它来进行我们自己的项目。

    • jquery.jscrollpane.js是 jScrollPane 插件的源代码。如果我们想要修改插件的工作方式或深入研究源代码,我们可以使用这个文件,但我们现在还不是专家级的程序员,所以我们可以暂时不管它。为什么文件名以jquery.开头?将jquery.添加到文件名前面以标记为 jQuery 插件是一种常见做法。在使用了十几个或更多 jQuery 插件以及其他 JavaScript 文件的大型项目中,这样可以更容易地找到 jQuery 插件。

    • jquery.jscrollpane.min.js是插件的压缩版本。它和jquery.jscrollpane.js是相同的代码,只是进行了压缩。这意味着所有额外的空格、制表符等都被移除,使文件更小——你可以看到效果相当不错。压缩后的文件只有 16 KB,而常规文件则为 45 KB。如果我们打开它,我们将无法轻松地阅读此文件,但这没关系。我们不需要能够阅读它,更重要的是我们要为我们的站点访问者提供尽可能小的文件。

    • jquery.mousewheel.js是我们将用于自定义滚动条的另一个插件。它是一个让我们的鼠标滚轮在可滚动区域中正常工作的插件。

    • mwheelintent.js是另一个插件。浏览 凯尔文·拉克 的文档,我们发现这个插件用于确保当我们将可滚动区域嵌套在彼此内时,它们的工作方式与我们期望的一样。但现在我们不需要它。

  7. 复制jquery.jscrollpane.min.jsjquery.mousewheel.js并将它们放在你的scripts文件夹内,紧挨着jquery.js文件。

  8. 接下来,我们需要像之前引入 jQuery 一样,在我们的页面中包含这两个文件。滚动到页面底部,在 jQuery 的<script>标签和你自己的<script>标签之间附加新文件:

    <script src="img/jquery.js"></script>
    <script src="img/jquery.mousewheel.js"></script>
    <script src="img/jquery.jscrollpane.min.js"></script>
    <script src="img/scripts.js"></script>
    </body>
    </html>
    
    

    小贴士

    每当你使用 jQuery 插件时,你要确保你的<script>标签的顺序是正确的。jQuery 的<script>标签应始终排在第一位,任何插件将紧随其后。最后是任何使用 jQuery 或插件的脚本。这是因为浏览器将按照我们指定的顺序加载这些脚本。插件文件需要在 jQuery 之后加载,因为它们正在使用 jQuery 库,并依赖于它在可用之前工作。在 JavaScript 中,我们称之为依赖关系。插件代码依赖于 jQuery。反过来,我们自己的代码依赖于插件代码和 jQuery 库本身,因此需要在这些可用后加载。

    在这种情况下,我们有一个额外的依赖项需要注意。jScrollPane 插件依赖于 MouseWheel 插件。因此,我们需要确保首先加载 MouseWheel 插件,然后加载 jScrollPane 插件。如果您遇到了 jQuery 或插件无法工作的问题,检查您的脚本顺序是个好主意 —— 缺少或顺序错误的依赖关系通常是原因。

    我们几乎准备好设置滚动条了,但还有一个文件我们需要包含。jScrollPane 插件实际上通过隐藏浏览器的原生滚动条并从普通的<div><span>构建替代品来工作。这意味着我们需要一些 CSS 来样式化那些<div><span>,使它们看起来像滚动条。稍后,我们将看看如何编写我们自己的 CSS 来使我们的滚动条看起来任何我们想要的样子,但现在,我们将使用 Kelvin Luck 提供的 CSS 来保持简单。

  9. 回到我们从 Github 下载的文件中,找到style文件夹。在文件夹内,你会找到两个文件:demo.cssjquery.jscrollpane.css。就像脚本文件一样,demo.css是专门为示例编写的特殊代码,但jquery.jscrollpane.css是将为我们的滚动条设置样式的文件。将该文件复制到您自己的styles文件夹中,然后在文档的<head>部分,在您自己的styles.css文件之前附加新样式表:

    <head>
    <title>Custom Scrollbars</title>
    <link rel="stylesheet" href="styles/jquery.jscrollpane.css"/>
    <link rel="stylesheet" href="styles/styles.css"/>	
    </head>
    
    
  10. 哎呀!我们已经做了很多工作,但我们仍然需要将我们的自定义滚动条添加到我们的页面中。别担心,在真正的 jQuery 风格中,这只是几行代码。打开您的scripts.js文件,添加以下代码:

    $(document).ready(function(){
    $('#scrolling').jScrollPane();
    });
    
    

    现在,如果您刷新页面,您将看到我们的可滚动区域现在有一个 jScrollPane 风格的滚动条。

    操作时间 —— 简单自定义滚动条

刚刚发生了什么?

让我们分解最后一段代码,以理解发生了什么。

我们已经熟悉了这个:

$(document).ready();

这是在文档上调用的 jQuery 对象的 ready 方法。这意味着我们将在文档准备就绪时运行我们的代码。像往常一样,我们通过向该方法传递一个函数来告诉 jQuery 在文档准备就绪时应该发生什么:

$(document).ready(function(){
//our code will go here
});

所以我们要看的唯一真正新的东西就是我们写在函数内的代码行:

$('#scrolling').jScrollPane();

但即使这一点我们也能理解至少一点。我们知道$('#scrolling')将选择页面上id为 scrolling 的项目。记住,我们在我们想要滚动的文本段落周围包裹了<div id="scrolling"></div>。然后我们使用了一些 CSS 来限制#scrolling div的高度并显示浏览器的滚动条。

然后我们可以看到我们正在调用 jScrollPane() 方法。大多数 jQuery 插件都是这样工作的 —— 通过添加一个你可以调用的新方法。你如何知道新方法的名称是什么?你通常会在插件的文档中找到它。jScrollPane 文档详尽,提供了大量的示例供你学习和修改。

添加箭头控件

好的,现在我们已经掌握了使用插件的基础知识,现在我们可以看看如何进一步使用它。

行动时间 —— 添加上下箭头

让我们给我们的滚动条添加上下按钮,这样我们的滚动条看起来和行为更像原生的滚动条。

  1. 让我们回到我们的 scripts.js 文件中调用 jScrollPane() 方法创建自定义滚动条的那行代码:

    $('#scrolling').jScrollPane();
    
    

    记得我们如何通过将它们放在括号里传递给方法和函数的吗?我们有以下例子:

    dog.eat('bacon');
    
    

    我们想说狗在吃培根。所以,在 JavaScript 中,我们向狗的 eat 方法传递了培根。

    好吧,在这种情况下,我们可以向 jScrollPane 方法传递一组选项,以控制我们的滚动条的外观和行为。我们想在我们的滚动条上显示顶部和底部箭头,我们可以通过将 showArrows 选项设置为 true 来实现。我们只需要对我们的代码做一个简单的修改:

    $('#scrolling').jScrollPane({showArrows:true});
    
    
  2. 现在当你刷新页面时,你会看到顶部和底部的滚动条上有方框,就像顶部和底部箭头会出现的地方一样。行动时间 —— 添加上下箭头

如果你点击这些框,你会发现它们的行为就像普通滚动条上的上下箭头一样。它们只是有点朴素 — 我们可以用一些 CSS 来为它们增加样式,让它们看起来任何我们想要的样子。

刚刚发生了什么?

我们将 jScrollPane 方法的 showArrows 选项设置为 true。这个插件提供了一长串高级选项,但幸运的是,我们不需要学习或了解它们全部才能充分利用它。

我们怎么知道有一个 showArrows 选项?我们会在插件的文档中找到它。一旦你更加了解 JavaScript 和 jQuery,你就能够阅读插件文件本身,查看插件为你提供的选项和方法。

要向方法传递一个选项,你需要用花括号括起来。然后你会输入你要设置的选项的名称(在本例中为showArrows),然后是一个冒号,然后是你要设置选项的值(在本例中为true表示显示箭头)。就像我们之前所做的一样:

$('#scrolling').jScrollPane({showArrows:true});

如果你想向一个方法传递多个选项,你需要做的一切都一样,只是在选项之间需要用逗号隔开。例如,如果我想在我的文本和滚动条之间添加一点间距,我可以通过为 verticalGutter 选项设置一个值来实现:

$('#scrolling').jScrollPane({ showArrows:true,verticalGutter:20});

现在,您可以看到,如果我设置了十几个或更多选项,这行代码会变得又长又难读。因此,将选项分开放在单独的行上是常见的做法,如下所示:

$('#scrolling').jScrollPane({
showArrows: true,
verticalGutter: 20
});

您可以看到内容和顺序是相同的,只是这个例子更容易被人读到和理解。计算机无论如何都不会在意。

提示

注意不要在最后一个选项/值对之后添加额外的逗号。大多数浏览器会优雅地处理这个错误,但是 Internet Explorer 会抛出错误,您的 JavaScript 将无法工作。

自定义滚动条样式

现在我们的滚动条上有了顶部和底部按钮,让我们将它们的外观调整得正好符合我们的要求。我们可以编写自己的 CSS 样式来设置滚动条的外观。

如果您花了一些时间来调试 CSS,那么您肯定已经知道您喜欢的浏览器中为您提供的调试工具。以防您还不知道,我强烈建议您看看 Firefox 的 Firebug 扩展,或者 Opera、Chrome、Safari 和 IE9 内置的开发工具。通过快速的谷歌搜索“您的浏览器 开发者工具教程”应该能够获得很多教程,让您学会如何充分利用这些工具所提供的便利。

如果您使用的是 IE 的旧版本,那么看看Debug Bar能帮助您调试 CSS 问题的 IE 扩展程序。这个扩展程序可以免费个人使用。

我在开发新页面时倾向于使用 Google Chrome。要访问 Chrome 中的开发者工具,请单击工具栏最右侧的扳手图标,然后选择工具 | 开发者工具。这是使用内置工具可以得到的 CSS 信息的一个例子:

自定义滚动条样式

在左侧,您可以看到我的文档的 DOM —— 构成文档树的所有 HTML 元素。我可以与之交互 —— 每个节点都可以被展开或折叠,以显示或隐藏嵌套在内的元素。在这种情况下,高亮显示的元素是我们 jScrollPane 滚动条的容器。

在右侧,我可以看到应用于左侧已选择元素的 CSS。我还可以看到特定 CSS 出现在哪个文件中,以及在哪一行。在这种情况下,大部分样式我的滚动条容器的 CSS 可以在jquery.jscrollpane.css文件的第 20 行找到。

通过这种方式深入 DOM 和 CSS 很快且容易地找出我们需要修改的 CSS 行,以满足我们所需的外观。

我们有几种选项来定制滚动条的 CSS。我们可以直接修改jquery.jscrollpane.css文件,也可以将这些样式复制到我们自己的样式表中进行更改。这是个人喜好的问题,但如果你选择直接修改jquery.jscrollpane.css文件,就像我在这里做的那样,那么我强烈建议你制作一个单独的副本以供参考,这样你就可以在不重新下载的情况下轻松地恢复它。

行动时间——添加我们自己的样式

  1. 打开jquery.jscrollpane.css。大约在第 56 行附近,你会找到为.jspTrack样式化的 CSS。这是我们滚动条的轨道,也可以说是背景区域。它的默认样式是淡紫色。

    .jspTrack
    {
    background: #dde;
    position: relative;
    }
    
    

    我们不想动位置,因为我们的滚动条依赖于它来正确工作,但你可以随意将背景颜色改为任何你喜欢的颜色、渐变或图片。我会选择淡粉色:

    .jspTrack
    {
    background: #fbebf3;
    position: relative;
    }
    The next style I'd like to change is for .jspDrag. This is the actual scrollbar handle. I'm going to make it bright pink:
    .jspDrag
    {
    background: #D33682;
    position: relative;
    top: 0;
    left: 0;
    cursor: pointer;
    }
    
    
  2. 接下来,我将处理顶部和底部按钮。我不仅有一个默认样式,还有一个禁用样式。例如,当滚动区域完全位于顶部时,顶部按钮被禁用,因为我不可能再向上滚动了。如果我用开发者工具检查按钮,我还可以看到按钮上有一个额外的类名,在默认 CSS 中没有样式化——顶部按钮有一个类名为jspArrowUp,底部按钮有一个类名为jspArrowDown。这将让我为上下按钮设置不同的样式——我将使用向上指向箭头的图片作为顶部箭头的背景,使用向下指向箭头作为底部按钮的背景,以便让我的网站访客清楚地了解它们的功能。

    这是我用来样式化它们的 CSS:

    .jspArrow
    {
    text-indent: -20000px;
    display: block;
    cursor: pointer;
    }
    .jspArrow.jspDisabled
    {
    cursor: default;
    background-color: #999;
    }
    .jspArrowUp
    {
    background: #d6448b url(../images/arrows.png) 0 0 no-repeat;
    }
    .jspArrowDown
    {
    background: #d6448b url(../images/arrows.png) 0 -16px no-repeat;
    }
    
    

刚刚发生了什么?

现在刷新浏览器,你会看到滚动条被样式化成了粉色——就像我想要的那样。我们修改了插件开发者提供的 CSS,使滚动条的外观符合我们的要求。我们能够使用浏览器内置的开发者工具来定位需要更新的代码的文件和行号,以改变滚动条的外观。

试试吧,勇士——按照你想要的样式设计滚动条

现在,也许你不喜欢鲜艳的粉红色滚动条,你可能会觉得我的示例有点平淡,你是对的。但是你可以创造性地使用背景颜色、渐变、图片、圆角等来设计你喜欢的滚动条样式。你可以模仿你喜欢的操作系统的滚动条,让你的所有网站访客都能看到你喜欢的样式,或者你可以创建一个全新的样式。尝试使用 CSS 来创建自己的滚动条样式。

平滑滚动

jScrollPane 是一个成熟且功能齐全的插件。如果你浏览示例和文档,你会发现各种有趣的选项可供使用。我将带你设置其中一个我最喜欢的功能:可滚动区域内的动画滚动。

行动时间 —— 设置平滑滚动

你可以将任何类型的内容放在可滚动区域内——新闻故事列表、照片画廊,或者是一篇包含几个部分、标题和副标题的长文章。下面是如何设置控件以平滑滚动到另一节的方法:

  1. 我们需要做的第一件事是为我们的每个段落分配一个 ID。我在可滚动区域中有五个 lorem ipsum 段落,所以我将它们分配为para1, para2, para3, para4para5ids。你可以选择任何你喜欢的ids,但请记住,id不能以数字开头。所以现在我的代码看起来像这样(我已经截断了文本以节省空间):

    <div id="scrolling">
    <p id="para1">Lorem ipsum...</p>
    <p id="para2">...</p>
    <p id="para3">...</p>
    <p id="para4">...</p>
    <p id="para5">...</p>
    </div>
    
    
  2. 现在,让我们在可滚动区域上方添加一些内部链接,以跳转到每个段落。在标题之后和可滚动区域之前,添加以下代码:

    <h2>We don't want this box of content to get too long, so we'll make it scroll:</h2>
    <p>Scroll to a paragraph:
    <a href="#para1">1</a>,
    <a href="#para2">2</a>,
    <a href="#para3">3</a>,
    <a href="#para4">4</a>,
    <a href="#para5">5</a>
    </p>
    <div id="scrolling">
    
    
  3. 如果我们禁用了 JavaScript,这些链接也可以工作;它们会将可滚动区域滚动到相关的段落,使其对我们的网站访客可见。但我们希望它们与我们的花哨自定义滚动条一起工作。因此,我们只需向 jScrollPane 方法传递一个新选项:

    $(document).ready(function(){
    $('#scrolling').jScrollPane({
    showArrows: true,
    verticalGutter: 30,
    hijackInternalLinks: true
    });
    });
    
    

    这个新选项是为了阻止浏览器在点击内部链接时尝试其默认行为。刷新页面,然后尝试点击段落的链接。

  4. 它可以运行,但并不完美,当可滚动区域突然跳动时可能会让人感到不安——我们的网站访客可能不会完全意识到发生了什么。让我们通过平滑地动画化跳转到不同的段落来明显地展现出来。我们只需在代码中添加另一个选项:

    $(document).ready(function(){
    $('#scrolling').jScrollPane({
    showArrows: true,
    verticalGutter: 30,
    hijackInternalLinks: true,
    animateScroll: true
    });
    });
    
    

    现在,当你刷新页面并点击段落链接时,你会发现可滚动区域平滑滚动到正确的段落。很容易理解发生了什么,你在页面上和可滚动区域中的位置。

刚刚发生了什么?

我们利用了 jScrollPane 插件的一个功能,并使得在可滚动容器内平滑滚动到任何内容成为可能。我们可以使用的选项和值都在插件的文档和示例中有所说明。由于插件作者在使艰难的事情变得容易方面的努力工作,你可以看到我们有多么容易地定制了这个插件来添加这种良好的行为。

总结

哦,这一章真是够繁重的。我们学到了关于 jQuery 插件的知识,如何使用它们,以及如何使用它们提供的选项来定制它们。我们了解了依赖关系,并按正确的顺序将多个脚本插入到我们的文件中。我们使用了 Kelvin Luck 的出色 jScrollPane 插件,将我们无聊的操作系统滚动条替换为我们自己设计的花哨的自定义滚动条。而且,好处是,它们的工作方式与浏览器的滚动条完全相同,我们的网站访问者可以点击轨道,点击上下按钮,他们可以拖动手柄,或者使用鼠标滚轮在我们设置的可滚动区域上下导航。这既提升了美观性又提高了可用性。

最后,我们学会了如何在可滚动区域内平稳滚动至锚点,这样我们的网站访问者就可以轻松地进入可滚动区域内的各个内容片段,并清楚地传达了正在发生的事情。

接下来,我们将看看如何用我们自己设计的漂亮工具提示覆盖浏览器的默认工具提示,并学习如何通过添加额外内容使它们更加有效。

第五章:制作自定义工具提示

现在我们已经看到插件有多强大以及它们如何轻松地实现高级功能,让我们看看如何利用另一个插件来制作自定义工具提示。

当您包含title属性时,浏览器会自动创建工具提示 —— 通常在链接或图像上。当您的网站访客将鼠标悬停在该项上或通过按 Tab 键将焦点移到该项上时,工具提示将显示 —— 通常为一个看起来悬浮在页面上的小黄色框。工具提示是向页面添加一些附加信息的好方法。屏幕阅读器软件会为使用辅助技术的残障网站访客朗读出工具提示文本,从而增强可访问性。此外,图像和链接上的title属性可以帮助搜索引擎更有效地索引您的内容。

在本章中,我们将学习:

  • 如何使用克雷格·汤普森的 qTip 插件来替换浏览器的默认工具提示

  • 如何自定义 qTip 工具提示的外观

  • 如何通过自定义工具提示增强导航栏

  • 如何在自定义工具提示中显示 Ajax 内容

简单的自定义文本工具提示

希望我已经说服了你,title 属性对于增强网站的可用性和可访问性都很棒。工具提示的唯一问题是它们无法以任何方式定制。每个浏览器都有自己的工具提示样式,并且这种样式不能通过 CSS 定制。有时这没关系,但有时控制工具提示的外观会更好。

行动时间 — 简单文本工具提示

我们将通过制作一个简单的替代浏览器默认工具提示的工具提示来开始工作,我们可以自定义样式:

  1. 设置一个基本的 HTML 文件以及像我们在第一章中所做的那样的相关文件和文件夹,设计师,见 jQuery。我们的 HTML 文件应包含一组链接,每个链接都有一个像这样的title属性:

    <p>Here's a list of links:</p>
    <ul>
    <li><a href="home.html" title="An introduction to who we are and what we do">Home</a></li>
    <li><a href ="about.html" title="Learn more about our company">About</a></li>
    <li><a href="contact.html" title="Send us a message. We'd love to hear from you!">Contact</a></li>
    <li><a href="work.html" title="View a portfolio of the work we've done for our clients">Our Work</a></li>
    </ul>
    
    
  2. 在浏览器中打开该页面,并将鼠标移动到链接上。您将看到title属性中包含的文本显示为工具提示。工具提示出现的位置和外观取决于您的浏览器,但以下是我的浏览器(Mac OS 上的 Google Chrome)中的外观:行动时间 — 简单文本工具提示

  3. 现在,让我们将其美化一下,用我们自己的样式替换默认的浏览器工具提示。首先,我们需要下载克雷格·汤普森的 qTip 插件。可以从craigsworks.com/projects/qtip2获取。他的网站上列出了一些功能、几个示例演示、您需要学习使用插件的文档、一个可以获取帮助的论坛,并且所需的文件可供下载。转到下载页面,您将看到一个选项清单,帮助您下载正确的版本。

    让我们逐个部分地浏览此页面:

    操作时间 —— 简单文本工具提示

  4. 第 1 步为我们提供了多种下载脚本的选项。在标题为版本的部分,我将选择稳定版本,这样我就可以得到经过彻底测试的最新版本的脚本。那些想要在开发者开发插件时尝试和测试插件的人可以选择夜间版本。

  5. 额外部分,我将取消jQuery 1.5的选择,因为我已经下载了 jQuery 并将其附加到我的项目中。如果您正在启动一个新项目,并且还没有下载 jQuery,您可以将其选中以与插件同时下载 jQuery。

  6. 样式部分,我将保留所有三组样式选中,因为我希望尽可能多地选择样式来设置我的工具提示。同样,在插件部分,我将保留所有选项选中,因为我将会使用各种不同类型的工具提示,并利用这些不同的功能。如果你只想创建简单的基于文本的工具提示,你可以取消所有这些额外的选项,这样可以得到一个更小的下载文件。这些额外的功能只在你要利用额外功能时才需要。这个插件的一个很好的功能是,我们可以挑选我们想要的功能,以尽可能保持我们的 JavaScript 文件尽可能小。

  7. 第 2 步为那些正在更新他们的代码,可能之前使用了插件的早期版本的任何人提供了一个自动转换器。由于我们是 qTip 插件的新手,所以我们可以忽略这一步。

  8. 第 3 步为我们提供了一个机会,告诉插件开发者我们的网站使用了插件,并有机会被列入插件主页的画廊中。由于在本章节中我们只是做了一些练习,所以我们现在不会使用这个,但这可能是你以后在自己的项目中考虑的事情。

  9. 第 4 步要求我们接受许可证的条款。该插件根据开源 MIT 和 GPLv2 许可证授权,这使得我们可以自由使用、修改甚至重新分发代码,只要在文件中包含许可证或链接到许可证。当您下载这些文件时,许可证已经包含在插件文件中了,所以只要您不编辑这些文件以删除许可证,您就不会有问题。

  10. 最后,我们可以点击下载 qTip按钮,您的浏览器将为您下载一个 ZIP 文件。解压它并检查其内容。在内部,我们会找到两个 CSS 文件和两个 JavaScript 文件。(如果您选择同时下载 jQuery 和插件脚本,可能会有一个额外的 JavaScript 文件)。操作时间 —— 简单文本工具提示

  11. 让我们从两个 CSS 文件开始。我们有jquery.qtip.cssjquery.qtip.min.css。这两个文件的内容完全相同。它们之间的区别在于第二个文件被缩小了,使其更小且更适合在生产中使用。另一个文件是开发版本,如果我们想要为我们的工具提示编写自己的样式而不是使用预构建的样式,我们可以轻松地编辑它或将其用作示例。您将选择其中一个文件并将其附加到您的页面上。在本示例中,为了使文件尽可能小,我将使用文件的经过缩小的版本,因为此时我不想编写自己的样式。将jquery.qtip.min.css复制到您自己的styles文件夹中,然后将文件附加到 HTML 文档的<head>部分:

    <head>
    <title>Chapter 5: Creating Custom Tooltips</title>
    <link rel="stylesheet" href="styles/jquery.qtip.min.css"/>
    <link rel="stylesheet" href="styles/styles.css"/>
    </head>
    
    

    我将 qTip 样式表附加到自己的styles.css之前,这样如果需要,我就可以更轻松地覆盖 qTip 样式表中的样式。

  12. 接下来,让我们看看 JavaScript 文件。我们有jquery.qtip.jsjquery.qtip.min.js。就像 CSS 文件一样,这是同一个文件的两个不同版本,我们只需选择一个并将其附加到我们的 HTML 文档即可。第一个文件jquery.qtip.js是文件的开发版本,大小为 94K,而第二个文件是经过缩小的,只有 41K。由于我们不需要编辑插件,而是要直接使用它,让我们选择经过缩小的版本。将jquery.qtip.min.js复制到您自己的scripts文件夹中,并将其附加到 HTML 文件底部,在 jQuery 和我们自己的scripts.js文件之间:

    <script src="img/jquery.js"></script>
    <script src="img/jquery.qtip.min.js"></script>
    <script src="img/scripts.js"></script>
    </body>
    </html>
    
    
  13. 我们需要做的最后一件事是调用插件代码。打开您的scripts.js文件并添加文档准备好的语句和函数:

    $(document).ready(function(){
    });
    
    
  14. 在函数内部,选择文档中所有具有title属性的链接,并在这些链接上调用qtip()方法:

    $(document).ready(function(){
    $('a[title]').qtip();
    });
    
    
  15. 现在,当您在浏览器中查看页面并将鼠标移动到具有title属性的链接上时,您将看到 qTip 样式的工具提示,而不是浏览器的默认工具提示:操作时间 —— 简单文本工具提示

  • 更好的是,无论我们使用哪个浏览器和操作系统,这些工具提示都会以相同的样式显示。

刚才发生了什么?

我们下载了 qTip 插件并将一个 CSS 文件和一个 JavaScript 文件附加到我们的 HTML 文档中。然后我们只添加了几行 jQuery 代码来激活自定义工具提示。

我们选择了页面上所有具有title属性的链接元素。我们利用了 jQuery 的属性选择器来实现这一点:

$('a[title]')

在我们的元素选择器后面加上title括号意味着我们只想要页面上具有title属性的链接。

一旦我们选择了这些链接,剩下的就是调用 qTip 插件为我们提供的qtip()方法了。qtip()方法会处理所有需要做的动作,以替换默认的工具提示为自定义的工具提示。但是如果我们想使用 qTip 配备的其他样式呢?

自定义 qTip 的外观

毫无疑问,当鼠标悬停在链接上时,qTip 的左上角与链接的右下角对齐,工具提示显示为黄色方框并且侧边有一个小箭头。qTip 插件提供了很多选项来定制工具提示的位置和外观,而且使用起来直观而易懂。

实战任务 — 自定义 qTips

让我们来看一下我们对自定义 qTip 工具提示外观的选项:

  1. 假设我们想改变工具提示的位置。qTip 为我们在页面上定位工具提示提供了很多选项。

  2. 我们可以把工具提示的任何一个点与链接的任何一个点匹配起来:实战任务 — 自定义 qTips

  3. 在这个例子中,我们将把链接右侧的中间和工具提示左侧的中间匹配起来,这样工具提示就会直接出现在链接的右侧。我们只需要向qTip()方法传递一些额外的信息。我们将继续使用上一个例子中设置的文件。打开你的scripts.js文件,并将这些额外的信息传递给qtip()方法:

    $('a[title]').qtip({
    position: {
    my: 'center left',
    at: 'center right'
    }
    });
    
    

    开发人员的目标是使之用通俗的语言来解释。从工具提示的角度来说,我们将把我的中心左侧与链接的中心右侧对齐。当我们在浏览器中刷新页面时,你会看到工具提示现在直接出现在链接的右侧。

    实战任务 — 自定义 qTips

  4. 除了改变工具提示的位置,我们还可以改变工具提示本身的外观。插件中包含的 CSS 包括几种颜色方案和样式。通过向我们的工具提示添加 CSS 类,可以应用不同的颜色和样式。让我们看看如何添加这些 CSS 类。

    $('a[title]').qtip({
    position: {
    my: 'center left',
    at: 'center right'
    },
    style: {
    classes: 'ui-tooltip-blue'
    }
    });
    
    

    现在当我们在浏览器中查看工具提示时,我们发现它是蓝色的:

    实战任务 — 自定义 qTips

  5. qTip 提供的颜色方案包括:

    • ui-tooltip(默认的黄色方案)

    • ui-tooltip-light(在白色工具提示上的黑色文字)

    • ui-tooltip-dark(在深灰色工具提示上的白色文字)

    • ui-tooltip-red

    • ui-tooltip-green

    • ui-tooltip-blue

      你可以将这些类中的任意一个添加到你的工具提示中,以调整颜色方案。

  6. 对于支持 CSS3 的浏览器,qTip 还提供了一些更花哨的样式。这些样式在不支持 CSS3 规范的浏览器中看不到,但在大多数情况下,这应该没问题。这些样式可以被视为对能够显示它们的浏览器的渐进增强。使用较低版本浏览器的网站访问者仍然可以看到和阅读提示,没有任何问题。他们只是看不到应用了更花哨的样式。可用的样式如下所示:操作时间 — 自定义 qTips

  7. 与配色方案一样,我们可以通过向提示添加 CSS 类来利用这些样式。可以像这样向提示添加多个 CSS 类:

    $('a[title]').qtip({
    position: {
    my: 'center left',
    at: 'center right'
    },
    style: {
    classes: 'ui-tooltip-blue ui-tooltip-shadow'
    }
    });
    
    

    此代码创建了一个蓝色带阴影的提示。

刚才发生了什么?

我们看到了如何将位置和样式值传递给 qTip 方法以自定义我们的提示外观。我们了解了 qTip 插件包含的颜色方案和样式,并学会了如何在我们自己的页面中使用这些样式来自定义 qTip 提示。

提示的自定义样式

如果没有任何可用选项完全适合我们的站点,我们还可以编写自己的颜色方案和样式。

操作时间 — 编写自定义提示样式

让我们看看如何编写我们自己的 qTip 提示的自定义样式,编写一个新的紫色配色方案:

  1. 我们将开始检查编码了红色提示样式的 CSS,这是 qTip 自带的。你会在随 qTip 下载的 jquery.qtip.css 文件中找到这段 CSS。以下是影响红色提示的所有 CSS 样式:

    /*! Red tooltip style */
    .ui-tooltip-red .ui-tooltip-titlebar,
    .ui-tooltip-red .ui-tooltip-content{
    border-color: #D95252;
    color: #912323;
    }
    .ui-tooltip-red .ui-tooltip-content{
    background-color: #F78B83;
    }
    .ui-tooltip-red .ui-tooltip-titlebar{
    background-color: #F06D65;
    }
    .ui-tooltip-red .ui-state-default .ui-tooltip-icon{
    background-position: -102px 0;
    }
    .ui-tooltip-red .ui-tooltip-icon{
    border-color: #D95252;
    }
    .ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{
    border-color: #D95252;
    }
    
    
  2. 通过检查这段 CSS,我们可以看到要创建新的颜色方案,我们只需要创建一个新的类名和四种紫色色调来创建新的样式。这是我的紫色配色方案的 CSS。打开你的 styles.css 文件并添加这些样式:

    /*! Purple tooltip style */
    .ui-tooltip-purple .ui-tooltip-titlebar,
    .ui-tooltip-purple .ui-tooltip-content{
    border-color: #c1c3e6;
    color: #545aba;
    }
    .ui-tooltip-purple .ui-tooltip-content{
    background-color: #f1f2fa;
    }
    .ui-tooltip-purple .ui-tooltip-titlebar{
    background-color: #d9daf0;
    }
    .ui-tooltip-purple .ui-state-default .ui-tooltip-icon{
    background-position: -102px 0;
    }
    .ui-tooltip-purple .ui-tooltip-icon{
    border-color: #c1c3e6;
    }
    .ui-tooltip-purple .ui-tooltip-titlebar .ui-state-hover{
    border-color: #c1c3e6;
    }
    
    
  3. 现在,要利用我们的新紫色提示样式,我们只需调整我们的 jQuery 代码,将新创建的 ui-tooltip-purple 类添加到我们的提示中。打开 scripts.js 文件并调整添加到提示中的类:

    $('a[title]').qtip({
    position: {
    my: 'center left',
    at: 'center right'
    },
    style: {
    classes: 'ui-tooltip-purple'
    }
    });
    
    

    现在,在浏览器中预览链接时,你将看到一个紫色的提示,如下截图所示:

    操作时间 — 编写自定义提示样式

刚才发生了什么?

使用 qTip 提供的一个 CSS 类,我们编写了自己的自定义样式并将其应用到了我们的提示中。你可以使用任何 CSS 样式来为 qTip 提示创建自定义外观。当你开始混合颜色和字体选择、背景图片、边框样式等时,几乎没有限制样式的可能性。

动手试试 — 创建自己设计的提示

尝试编写自己的 CSS 类来为提示样式。尝试新的配色方案、新的字体样式和大小、文字阴影、盒阴影 — 任何你能想到的,以使提示与网站设计相匹配或真正突出。

使用工具提示增强导航

一旦你知道如何制作自定义工具提示,你会发现它们有很多可能的用途。让我们看看如何使用 qTip 插件增强标准导航栏的自定义工具提示。

行动时间 —— 建立一个花哨的导航栏

让我们看看如何使用定制设计的工具提示为基本导航栏添加一些逐步增强的效果:

  1. 让我们从设置一个带有关联文件夹和文件的基本 HTML 页面开始,就像我们在第一章中所做的一样,Designer, Meet jQuery。在文档的主体中,包含一个简单的导航栏,就像这样:

    <ul id="navigation"> <li><a href="home.html" title="An introduction to who we are and what we do">Home</a></li>
    <li><a href ="about.html" title="Learn more about our company">About</a></li>
    <li><a href="contact.html" title="Send us a message. We'd love to hear from you!">Contact</a></li>
    <li><a href="work.html" title="View a portfolio of the work we've done for our clients">Our Work</a></li>
    </ul>
    
    
  2. 接下来,我们将为我们的导航栏添加一些 CSS 样式。这里有很多 CSS,因为我正在使用渐变作为背景,而且目前不同的浏览器需要很多不同的 CSS。将这些 CSS 行添加到你的styles.css文件中。如果你喜欢不同的风格,请随意自定义 CSS 以适应你自己的口味:

    #navigation {
    background: rgb(132,136,206); /* Old browsers */
    background: -moz-linear-gradient(top, rgba(132,136,206,1) 0%, rgba(72,79,181,1) 50%, rgba(132,136,206,1) 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(132,136,206,1)), color-stop(50%,rgba(72,79,181,1)), color-stop(100%,rgba(132,136,206,1))); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top, rgba(132,136,206,1) 0%,rgba(72,79,181,1) 50%,rgba(132,136,206,1) 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top, rgba(132,136,206,1) 0%,rgba(72,79,181,1) 50%,rgba(132,136,206,1) 100%); /* Opera11.10+ */
    background: -ms-linear-gradient(top, rgba(132,136,206,1) 0%,rgba(72,79,181,1) 50%,rgba(132,136,206,1) 100%); /* IE10+ */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#8488ce', endColorstr='#8488ce',GradientType=0 ); /* IE6-9 */
    background: linear-gradient(top, rgba(132,136,206,1) 0%,rgba(72,79,181,1) 50%,rgba(132,136,206,1) 100%); /* W3C */
    list-style-type: none;
    margin: 100px 20px 20px 20px;
    padding: 0;
    overflow: hidden;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
    }
    #navigation li {
    margin: 0;
    padding: 0;
    display: block;
    float: left;
    border-right: 1px solid #4449a8;
    }
    #navigation a {
    color: #fff;
    border-right: 1px solid #8488ce;
    display: block;
    padding: 10px;
    }
    #navigation a:hover {
    background: #859900;
    border-right-color: #a3bb00;
    }
    
    
  3. 现在我们的页面上有了一个水平的导航栏,就像这样:行动时间 —— 建立一个花哨的导航栏

  4. 我在我的链接上包含了title属性,当我将鼠标移动到导航链接上时,它们是可见的。我想用友好的对话框替换这些无聊的浏览器默认工具提示,在我的导航下方。

  5. 就像我们在上一个例子中所做的那样,我们要复制 qTip 的 CSS 和 JavaScript 到我们自己的 styles 和 scripts 文件夹中,并将它们附加到 HTML 文档中:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Chapter 5: Creating Custom Tooltips</title>
    <link rel="stylesheet" href="styles/jquery.qtip.min.css"/>
    <script src="img/jquery.js"></script>
    <script src="img/jquery.qtip.min.js"></script>
    <script src="img/scripts.js"></script>
    </body>
    </html>
    
    
  6. 接下来,打开你的scripts.js文件,这样我们就可以调用qtip()方法并传递我们的自定义内容。我们将几乎像上次那样开始,只是我们将使用不同的选择器,因为我们只想选择导航栏内的链接:

    $(document).ready(function(){
    $('#navigation a').qtip();
    });
    
    

    现在默认的工具提示已经被 qTip 样式的工具提示替换了。

  7. 接下来,我们将为导航工具提示创建我们自己的样式,所以我们将编写一些新的 CSS 使它们看起来像对话框。将这些样式添加到你的styles.css文件中:

    .ui-tooltip-conversation .ui-tooltip-titlebar,
    .ui-tooltip-conversation .ui-tooltip-content{
    border: 3px solid #555;
    filter: none; -ms-filter: none;
    }
    .ui-tooltip-conversation .ui-tooltip-titlebar{
    background: #859900;
    color: white;
    font-weight: normal;
    font-family: serif;
    border-bottom-width: 0;
    }
    .ui-tooltip-conversation .ui-tooltip-content{
    background-color: #F9F9F9;
    color: #859900;
    -moz-border-radius: 9px;
    -webkit-border-radius: 9px;
    border-radius: 9px;
    padding: 10px;
    }
    .ui-tooltip-conversation .ui-tooltip-icon{
    border: 2px solid #555;
    background: #859900;
    }
    .ui-tooltip-conversation .ui-tooltip-icon .ui-icon{
    background-color: #859900;
    color: #555;
    }
    
    
  8. 现在我们已经准备好了新的工具提示 CSS 样式,我们只需将这个新类添加到工具提示中即可。回到scripts.js,并将新类添加到 JavaScript 中:

    $('#navigation a').qtip({
    style: {
    classes: 'ui-tooltip-conversation'
    }
    });
    
    
  9. 接下来,让我们将对话框定位到每个导航链接的下方。在scripts.js中,将位置信息传递给qtip()方法:

    $('#navigation a').qtip({
    position: {
    my: 'top center',
    at: 'bottom center'
    },
    style: {
    classes: 'ui-tooltip-conversation',
    width: '150px'
    }
    });
    
    
  10. 现在,我们需要控制工具提示的宽度,使其不要显得太宽。我们将宽度设置为 150px:

    $('#navigation a').qtip({
    position: {
    my: 'top center',
    at: 'bottom center'
    },
    style: {
    classes: 'ui-tooltip-conversation',
    width: '150px'
    }
    });
    
    
  11. 现在我们要做的最后一件事是改变工具提示从页面上出现和消失的方式。默认情况下,qTip 插件使用非常快速和微妙的淡入淡出效果。让我们改变一下,让工具提示滑入视图并滑出视图:

    $('#navigation a').qtip({
    position: {
    my: 'top center',
    at: 'bottom center'
    },
     show: {
    effect: function(offset) {
    $(this).slideDown(300);
    }
    },
    hide: {
    effect: function(offset) {
    $(this).slideUp(100);
    }
    },
    style: {
    classes: 'ui-tooltip-conversation',
    
    width: '150px'
    }
    });
    
    
  12. 现在当您在浏览器中查看页面时,您可以看到对话气泡在您将鼠标悬停在链接上时从下方滑入视图,并在您将鼠标移出链接时滑出视图。

刚刚发生了什么?

我们回顾了如何创建和附加自定义 CSS 样式到 qTip 的工具提示,以及如何定位工具提示在任何你想要的位置。我们还学会了如何控制工具提示的宽度,以确保我们得到统一的大小。

然后我们看到了如何覆盖默认的显示和隐藏行为,并用自定义动画替换它们。在这种情况下,我们使用了 jQuery 的 slideDown() 效果来显示工具提示。我们向 slideDown() 方法传递了一个值为 300,这意味着动画将花费 300 毫秒完成,或者大约三分之一秒。我发现如果动画持续时间超过这个时间,网站访客会因等待而感到不耐烦。

接下来,我们使用 jQuery 的 slideUp() 方法覆盖了默认的隐藏行为。我传递了一个值为 100,意味着动画将在大约十分之一秒内完成。当此动画运行时,网站访客已经决定继续前进,因此最好尽快将信息移出他们的视线。

在工具提示中显示其他内容

到目前为止,我们已经看到了如何自定义 qTip 工具提示的外观,控制它们的外观、动画和位置。然而,我们只是用工具提示来显示文本,即我们放置在链接的 title 属性中的文本。然而,我们有更强大的选项。我们可以加载几乎任何内容到我们的工具提示中。我们还可以确保当项目被点击而不是悬停在上面时出现工具提示。让我们看看当我们点击链接时如何将内容从另一个 HTML 页面加载到我们的工具提示中。

在本节中,我们将首次深入使用 Ajax。如果您不熟悉,Ajax 是一种从服务器获取一些新内容并将其显示给网站访问者的方法,而无需完全刷新页面。因为浏览器只是获取并显示网站访问者所需的那一部分信息,所以它通常会更快速、更敏捷。

在我们第一次深入 Ajax 之前,先简单说明一下。现代浏览器有很多对 Ajax 请求的安全规定。你不会像之前那样简单地在浏览器中查看你的 ajaxified HTML 文件。为了观看 Ajax 的操作,你要么必须将你的文件上传到服务器上,然后再查看它们,要么你必须在自己的电脑上搭建一个服务器。如果你是 Mac 用户,我强烈推荐使用MAMP,它有免费和高级付费版本。你可以从www.mamp.info获取更多信息并下载 MAMP。如果你使用 Windows,我强烈推荐使用WampServer,它是免费的。你可以从www.wampserver.com.获取更多信息并下载 WampServer。

行动时间 - 创建自定义 Ajax 工具提示

按照以下步骤设置一些显示 Ajax 内容的工具提示:

  1. 我们将从创建一个 HTML 文档和相关文件夹和文件开始,就像我们在第一章 设计师,遇见 jQuery中所做的那样。我们的 HTML 页面应该包含一些段落文字,其中有一些链接指向更多信息。我的第一个 HTML 文档看起来如下:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Pittsburgh, Pennsylvania</title>
    <link rel="stylesheet" href="styles/styles.css"/>
    </head>
    <body>
    <h2>Pittsburgh, Pennsylvania</h2>
    <p>Pittsburgh is the second-largest city in the US Commonwealth of Pennsylvania and the county seat of Allegheny County. Regionally, it anchors the largest urban area of Appalachia and the Ohio River Valley, and nationally, it is the 22nd-largest urban area in the United States. The population of the city in 2010 was 305,704 while that of the seven-county metropolitan area stood at 2,356,285\. <a href="http://infoboxes/downtown.html">Downtown Pittsburgh</a> retains substantial economic influence, ranking at 25th in the nation for jobs within the urban core and 6th in job density.</p>
    <p>The characteristic shape of Pittsburgh's central business district is a triangular tract carved by the confluence of the Allegheny and Monongahela rivers, which form the Ohio River. The city features 151 high-rise buildings, 446 bridges, two inclined railways, and a pre-revolutionary fortification. Pittsburgh is known colloquially as "The City of Bridges" and "The Steel City" for its <a href="http://infoboxes/bridges.html">many bridges</a> and former steel manufacturing base.</p>
    <p>The warmest month of the year in Pittsburgh is July, with a 24-hour average of 72.6&deg;F. Conditions are often humid, and combined with the 90&deg;F (occurring on an average of 8.4 days per annum), a considerable <a href="http://infoboxes/heatindex.html">heat index</a> arises.</p>
    <script src="img/jquery.js"></script>
    <script src="img/scripts.js"></script>
    </body>
    </html>
    
    
  2. 我们需要一种轻松的方法来选择这三个更多信息链接,所以我们会像这样给每一个添加一个 CSS 类:

    <a href ="http://infoboxes/downtown.html" class="infobox">Downtown Pittsburgh</a>
    
    
  3. 接下来,我们需要创建一组简短的页面,每个页面中都包含一个链接和前文中链接的标题。以下是我其中一个简短 HTML 页面的示例:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Downtown Pittsburgh</title>
    </head>
    <body>
    <img src="img/downtown.jpg"/>
    <p>Downtown Pittsburgh</p>
    </body>
    </html>
    
    

    如你所见,文件非常小而简单。

  4. 在主页旁边创建一个infoboxes目录。将你的简单 HTML 文件保存到这个目录中,并为主文档中的每个链接创建更多的简单文件。

  5. 现在,如果你在浏览器中打开主页并点击文本中的链接,你会发现这些简短而普通的页面加载到了浏览器中。我们已经掌握了基本功能,接下来我们将逐步增强页面功能,以满足那些启用了 JavaScript 的用户。

  6. 我们将使用在本章前面设置的紫色配色方案来为我们的工具提示添加 CSS,所以让我们把ui-tooltip-purple类的 CSS 添加到styles.css文件中:

    /*! Purple tooltip style */
    .ui-tooltip-purple .ui-tooltip-titlebar,
    .ui-tooltip-purple .ui-tooltip-content{
    border-color: #c1c3e6;
    color: #545aba;
    }
    .ui-tooltip-purple .ui-tooltip-content{
    background-color: #f1f2fa;
    }
    .ui-tooltip-purple .ui-tooltip-titlebar{
    background-color: #d9daf0;
    }
    .ui-tooltip-purple .ui-state-default .ui-tooltip-icon{
    background-position: -102px 0;
    }
    .ui-tooltip-purple .ui-tooltip-icon{
    border-color: #c1c3e6;
    }
    .ui-tooltip-purple .ui-tooltip-titlebar .ui-state-hover{
    border-color: #c1c3e6;
    }
    
    
  7. 现在我们已经设置好了 HTML 和 CSS,让我们开始学习 JavaScript。在页面底部,介于 jQuery 和你的scripts.js文件之间,添加 qTip 插件:

    <script src="img/jquery.js"></script>
    <script src="img/jquery.qtip.min.js"></script>
    <script src="img/js"></script>
    </body>
    </html>
    
    
  8. 接下来,打开scripts.js,我们将开始使用我们的文档就绪功能:

    $(document).ready(function(){
    });
    
    
  9. 接下来,我们将以与以往略有不同的方式调用qtip()方法。在qtip()方法内部,我们需要轻松地获取与我们正在处理的链接相关的信息,因此我们将使用 jQuery 的each()方法逐个循环处理它们。代码如下:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip()
    });
    });
    
    
  10. 现在,如果你在浏览器中刷新页面,你会发现当你悬停在链接上时什么也不会发生。这是因为我们的链接没有title属性,默认情况下 qTip 插件正在寻找它。然而,我们可以覆盖默认值,插入我们想要的任何内容到我们的工具提示中。

  11. 我们将在工具提示中显示我们设置的简单 HTML 页面。尽管 Ajax 请求往往很快,但仍可能会有一些延迟,所以让我们准备使用 Ajax,在我们的站点访问者等待真正的内容显示时显示一个加载消息:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...'
    }
    });
    })
    });
    
    

    现在,当你在浏览器中刷新页面时,你会发现工具提示包含正在加载...的文本。

  12. 我们希望改变工具提示的行为,使其在点击链接时显示,而不是在鼠标悬停时显示。我们还希望确保页面上一次只能看到一个工具提示。如果站点访问者在另一个工具提示已经打开的情况下打开了一个工具提示,第一个工具提示应该关闭,以免他们在屏幕上到处打开许多工具提示。我们将这样做:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...'
    },
    show: {
    event: 'click',
    solo: true
    },
    });
    })
    });
    
    
  13. 现在,如果你在浏览器中刷新页面,你会发现当我们悬停在链接上时工具提示不再出现了。

  14. 但是,当我们现在点击链接时,我们被带到了我们设置的简单的 HTML 页面。我们必须告诉浏览器忽略这个链接,因为我们有其他计划。我们可以通过在我们早期的代码之上并在文档就绪语句内添加这一行代码来取消默认行为:

    $(document).ready(function(){
    $('a.infobox').bind('click', function(e){e.preventDefault()});
    $('a.infobox').each(function(){
    
    
  15. 我们在这里做的是绑定一个在链接被点击时触发的函数。我们的函数很简单。我们将当前链接传递给函数(在这种情况下是 e,为了简洁起见,但我们几乎可以将其命名为任何东西),然后告诉浏览器阻止默认链接行为。

    现在,如果你在浏览器中刷新页面,你会发现当我们点击链接时工具提示出现了 —— 点击链接不再将我们带到新页面。

  16. 但是我们可以用更简洁的方式编写我们的代码。记住,jQuery 允许我们链式调用方法,一个接一个。在这种情况下,我们可以直接将bind()方法链到我们之前编写的each()方法的末尾。新的 JavaScript 代码将如下所示:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...'
    },
    show: {
    event: 'click',
    solo: true
    },
    });
    }).bind('click', function(e){e.preventDefault()});
    });
    
    
  17. 接下来,让我们通过添加阴影和应用我们为工具提示编写的紫色配色方案来调整工具提示的样式:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...',
    },
    show: {
    event: 'click',
    solo: true
    },
    style: {
    classes: 'ui-tooltip-purple ui-tooltip-shadow'
    }
    });
    }).bind('click', function(e){e.preventDefault();});
    });
    
    

    现在,当你在浏览器中刷新页面时,你会发现我们有紫色的工具提示,带有阴影。我们离目标越来越近了。

  18. 接下来,让我们加入 Ajax 魔法,将我们的简单 HTML 页面加载到工具提示中。请记住,这只能从服务器上运行,所以要看到这一步的效果,你要么必须将文件上传到服务器上,要么在自己的计算机上设置一个服务器。

    要通知工具提示通过 Ajax 获取内容,我们只需要传递我们想要获取的内容的 URL。在这种情况下,我们已经链接到了那个内容。我们只需要从每个链接中获取链接 URL。我们可以通过使用 jQuery 的 attr() 方法很容易地获取到这个 URL。代码如下:

    $(this).attr('href')
    
    

    在这种情况下,$(this) 指的是当前链接。我调用 attr() 方法,并传递我想要获取的属性,在这种情况下,链接的 href 属性包含了我想要的信息。attr() 方法可以用于获取任何属性——图像的 src 属性,任何元素的 title 属性,表格的 cellspacing 属性,等等:

    $('img').attr('src')
    $('p').attr('title')
    $('table').attr('cellspacing')
    
    
  19. 现在我们知道如何获取我们链接的 href 属性,我们将使用它来告诉工具提示要使用哪个 URL 来获取工具提示的内容:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...',
    ajax: {
    url: $(this).attr('href')
    }
    },
    show: {
    event: 'click',
    solo: true
    },
    style: {
    classes: 'ui-tooltip-purple ui-tooltip-shadow'
    }
    });
    }).bind('click', function(e){e.preventDefault()});
    });
    
    
  20. 刷新浏览器,然后点击其中一个链接——你会看到紫色的工具提示弹出,显示我们简单的 HTML 页面中的 HTML 内容。使用 Ajax 获取内容是如此简单,是不是很惊人?

    现在,让我们对工具提示进行一些其他最后的调整,使它们变得更好。

  21. 首先,我们将为工具提示添加一个标题栏。为了获得一些自定义文本,让我们回到 index.html 文件中的每个链接,并添加一个包含要在工具提示顶部显示的文本的 title 属性:

    <a href ="http://infoboxes/downtown.html" class="infobox" title="Downtown Pittsburgh">Downtown Pittsburgh</a>
    ...
    <a href ="http://infoboxes/bridges.html" class="infobox" title="Pittsburgh Bridges">many bridges</a>
    <a href ="http://infoboxes/heatindex.html" class="infobox" title="Beating the Heat">heat index</a>
    
    
  22. 现在,我们可以以类似的方式获取这些链接的 title 属性,就像我们获取了 href 属性的 URL 一样,并将其传递给 qTip 作为工具提示的标题文本。顺便说一下,我们还可以为 button 传递一个 true 值,以在工具提示的右上角显示一个小的关闭按钮:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...',
    ajax: {
    url: $(this).attr('href')
    },
    title: {
    text: $(this).attr('title'), button: true
    }
    },
    show: {
    event: 'click',
    solo: true
    },
    style: {
    classes: 'ui-tooltip-purple ui-tooltip-shadow'
    }
    });
    }).bind('click', function(e){e.preventDefault()});
    });
    
    

    现在当你刷新浏览器,你会看到每个工具提示顶部会出现一个带有关闭按钮的较深色标题栏。

  23. 但是,如果你试图移动鼠标点击关闭按钮时,你会看到工具提示在你到达之前就消失了。我们将工具提示的显示值改为在点击时显示而不是鼠标悬停时显示,但我们从未改变隐藏值——当我们移开鼠标离开链接时,工具提示仍然被隐藏。这有点尴尬,所以我将隐藏值改为unfocus,这样当链接失去焦点或网站访问者单击工具提示的关闭按钮时,工具提示将被隐藏:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...',
    ajax: {
    url: $(this).attr('href')
    },
    title: {
    text: $(this).attr('title'),
    button: true
    }
    },
    show: {
    event: 'click',
    solo: true
    },
    hide: 'unfocus',
    style: {
    classes: 'ui-tooltip-purple ui-tooltip-shadow'
    }
    });
    }).bind('click', function(e){e.preventDefault()});
    });
    
    
  24. 刷新浏览器,你会发现交互现在好多了。我们网站的访问者不必小心将鼠标悬停在链接上以查看工具提示内的内容。而且我们的工具提示仍然容易移除——网站访问者可以点击关闭按钮,或者在页面上工具提示外的任何地方单击,工具提示就会隐藏起来。

  25. 现在,只剩下一件事要做,那就是将工具提示定位到我们希望它们出现的位置。我希望我的工具提示在链接下方居中显示,所以我将工具提示的顶部中心与链接的底部中心对齐:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...',
    ajax: {
    url: $(this).attr('href')
    },
    title: {
    text: $(this).attr('title'),
    button: true
    }
    },
    position: {
    my: 'top center',
    at: 'bottom center'
    },
    show: {
    event: 'click',
    solo: true
    },
    hide: 'unfocus',
    style: {
    classes: 'ui-tooltip-purple ui-tooltip-shadow'
    }
    });
    }).bind('click', function(e){e.preventDefault()});
    });
    
    

    现在,如果你在浏览器中刷新页面并点击链接,你会看到工具提示从默认位置滑动到指定位置。

  26. 我们的工具提示看起来不错,但我们仍然有一些问题。一个问题是工具提示从底角到中间位置的动画有点分散注意力。为了解决这个问题,让我们将 effect 值设置为 false。这样工具提示将直接出现在应该出现的位置,而不会有滑动到指定位置的动画效果。另一个问题是,根据浏览器窗口的大小,有时工具提示会被裁剪并显示在屏幕区域之外。为了确保这种情况不会发生,我们将 viewport 值设置为窗口,如下所示:

    $(document).ready(function(){
    $('a.infobox').each(function(){
    $(this).qtip({
    content: {
    text: 'Loading...',
    ajax: {
    url: $(this).attr('href')
    },
    title: {
    text: $(this).attr('title'),
    button: true
    }
    },
    position: {
    my: 'top center',
    at: 'bottom center',
    effect: false,
    viewport: $(window)
    },
    show: {
    event: 'click',
    solo: true
    },
    hide: 'unfocus',
    style: {
    classes: 'ui-tooltip-purple ui-tooltip-shadow'
    }
    });
    }).bind('click', function(e){e.preventDefault()});
    });
    
    
  27. 现在当你在浏览器中重新加载页面时,如果可能的话,工具提示将显示在链接下方的中心位置,但如果这会使其超出窗口区域,则工具提示将调整其位置以确保在与链接相关的最佳位置显示。我们失去了对工具提示出现位置的一些控制,但我们可以确保我们的网站访问者始终能够看到工具提示的内容,这更重要。

行动时间 — 构建自定义 Ajax 工具提示

摘要

在本章中,我们涵盖了很多内容。我们学习了如何使用 qTip 插件来替换浏览器默认的工具提示为自定义设计的工具提示。我们看到如何通过在导航栏中添加气泡工具提示来进一步定制化。最后,我们使用 Ajax 来拉取一些外部内容,不仅定制了工具提示的外观,还拉取了自定义内容,添加了标题栏和关闭按钮,确保工具提示始终可见,并定制了工具提示的显示和隐藏行为。我希望你能看到 qTip 插件有多灵活,以及它除了定制工具提示外还有多种用途。愿你在尝试插件文档中列出的所有不同设置时玩得开心,并发挥你在定制工具提示外观方面的创意。

接下来,我们将看看如何创建设计精美且动画效果出色的下拉式导航菜单。

第六章:构建交互式导航菜单

在 2003 年,A List Apart(alistapart.com)上发布的一篇文章叫做 Suckerfish Dropdowns 展示了如何仅使用 HTML 和 CSS(仅在 IE6 中稍微需要一点 JavaScript 帮助)就可以构建复杂的多级下拉菜单。Suckerfish 名字源自该技术的精美设计演示,其中包含了鲸鲨和寄生鱼的插图。虽然有用,但原始版本要求网站访客在导航时不要将鼠标移出菜单区域,否则菜单会消失。多年来,Suckerfish Dropdowns 激发了许多衍生产品 — Son of Suckerfish,Improved Suckerfish 等,试图解决原始版本的缺点。由于 jQuery 能够让一切变得更好,我们将使用 Superfish jQuery 插件来构建这个想法,使菜单更易于使用。

Superfish 插件的开发者 Joel Birch 表示,插件的大部分支持问题来自于人们不理解菜单的 CSS。为了确保你对 CSS 有牢固的掌握,我强烈建议阅读 A List Apart 上的原始 Suckerfish Dropdowns 文章,网址为 www.alistapart.com/articles/dropdowns

要开始使用此插件,我们将构建一个基本的 Suckerfish 菜单。由于该菜单仅需要 CSS,因此如果我们禁用 JavaScript,我们仍然可以获得一个交互式菜单。菜单只是针对启用 JavaScript 的用户进行了改进。

在本章中,我们将学习以下主题:

  • 使用 Superfish jQuery 插件创建水平下拉菜单

  • 使用 Superfish 插件创建垂直飞出菜单

  • 自定义使用 Superfish 插件创建的下拉和飞出菜单

水平下拉菜单

长期以来,水平下拉菜单一直是桌面软件中的常见项目,但在网站中实现起来可能很具挑战性,甚至是不可能的,直到 CSS 和 JavaScript 最终出现,使其成为可能。

行动时间 — 创建水平下拉菜单

让我们看看如何使用 Superfish 插件创建水平下拉菜单:

  1. 要开始,我们将创建一个简单的 HTML 页面和相关的文件夹和文件,就像我们在 第一章 中创建的那样,Designer, Meet jQuery。我们 HTML 文件的主体将包含一个嵌套的无序列表导航菜单,如下所示:

    <ul id="sfNav" class="sf-menu">
    <li><a href="#">Papilionidae</a>
    <ul>
    <li><a href="#">Common Yellow Swallowtail</a></li>
    <li><a href="#">Spicebush Swallowtail</a></li>
    <li><a href="#">Lime Butterfly</a></li>
    <li><a href="#">Ornithoptera</a>
    <ul>
    <li><a href="#">Queen Victoria's Birdwing</a></li>
    <li><a href="#">Wallace's Golden Birdwing</a></li>
    <li><a href="#">Cape York Birdwing</a></li>
    </ul>
    </li>
    </ul>
    </li>
    <li><a href="#">Pieridae</a>
    <ul>
    <li><a href="#">Small White</a></li>
    <li><a href="#">Green-veined White</a></li>
    <li><a href="#">Common Jezebel</a></li>
    </ul>
    </li>
    <li><a href="#">Lycaenidae</a>
    <ul>
    <li><a href="#">Xerces Blue</a></li>
    <li><a href="#">Karner Blue</a></li>
    <li><a href="#">Red Pierrot</a></li>
    </ul>
    </li>
    <li><a href="#">Riodinidae</a>
    <ul>
    <li><a href="#">Duke of Burgundy</a></li>
    <li><a href="#">Plum Judy</a></li>
    </ul>
    </li>
    <li><a href="#">Nymphalidae</a>
    <ul>
    <li><a href="#">Painted Lady</a></li>
    <li><a href="#">Monarch</a></li>
    <li><a href="#">Morpho</a>
    <ul>
    <li><a href="#">Sunset Morpho</a></li>
    <li><a href="#">Godart's Morpho</a></li>
    </ul>
    </li>
    <li><a href="#">Speckled Wood</a></li>
    </ul>
    </li>
    <li><a href="#">Hesperiidae</a>
    <ul>
    <li><a href="#">Mallow Skipper</a></li>
    <li><a href="#">Zabulon Skipper</a></li>
    </ul>
    </li>
    </ul>
    
    

    请注意,我们给包含菜单的 <ul> 添加了 idsfNavclasssf-menu。这样可以让我们更容易选择和样式化菜单。

    如果你在浏览器中查看页面,它会类似于以下的屏幕截图:

    行动时间 — 创建水平下拉菜单

    正如您所看到的,我们将链接组织成了一个层次结构。这对于查找我们想要的信息很有用,但占用了相当多的空间。这就是我们可以使用一种技术来隐藏额外信息直到需要它的时候的地方。

  2. 接下来,我们需要一个 Superfish 插件的副本。请转到users.tpg.com.au/j_birch/plugins/superfish/,在那里您将找到 Joel Birch 的 Superfish 插件可供下载,以及文档和示例。

    在 Joel 的快速入门指南中,我们看到实施 Superfish 插件有三个简单的步骤:

    • 编写 CSS 以创建 Suckerfish 样式的下拉菜单

    • 链接到superfish.js文件

    • 在包含您的菜单的元素上调用superfish()方法

    幸运的是,Joel 还包含了一个样式 CSS 文件的样本,所以我们可以快速开始。我们稍后会看看如何自定义菜单的外观,但现在,我们将继续使用与插件一起提供的 CSS。

  3. 点击下载和支持选项卡。操作时间——创建一个水平下拉菜单

    下载部分的第一个链接是下载 ZIP 文件的链接。在此之下,我们看到一个带有所有 ZIP 文件中包含的文件的项目列表,并提供了单独下载每个文件的链接。既然我们将使用其中的几个文件,我们将下载整个 ZIP 文件。点击Superfish-1.4.8.zip链接并将文件保存到您的计算机上。

  4. 解压文件夹并查看其中的内容:操作时间——创建一个水平下拉菜单

    我们会发现文件被很好地按类型组织到子目录中,还有一个示例 HTML 文件,我们可以查看以查看插件的工作原理。

  5. 我们从下载部分需要的第一个文件是css文件夹中的superfish.css文件。将该文件复制到您自己的styles文件夹中。

  6. 接下来,我们将编辑我们的 HTML 文件,将superfish.css文件包含在文档的头部:

    <head>
    <title>Chapter 6: Building an Interactive Navigation Menu </title>
    <link rel="stylesheet" href="styles/superfish.css"/>
    <link rel="stylesheet" href="styles/styles.css"/>
    </head>
    
    

    我们将在styles.css文件之前附加superfish.css文件,以便于我们稍后覆盖superfish.css文件中的任何样式。

  7. 现在,如果您在浏览器中刷新页面,您将看到一个可用的 Suckerfish 下拉菜单:操作时间——创建一个水平下拉菜单

当我将鼠标移到第一个链接上时,嵌套的<ul>变得可见。如果我将鼠标移到下拉菜单中的最后一个链接上,嵌套在第三级的<ul>就会变得可见。

请记住,所有这些都是在没有 JavaScript 的情况下完成的 — 只有 CSS。如果您花点时间使用该菜单,您可能很快就会意识到一些缺点。首先,如果我想要将我的鼠标从翻翼鸟链接移动到开普约克凤蝶链接,我的自然倾向是对角线移动鼠标。然而,一旦我的鼠标离开蓝色菜单区域,菜单就会关闭和消失。我必须调整移动我的鼠标直接移到子菜单上,然后向下移动到我感兴趣的链接。

行动时间 — 创建水平下拉菜单

这很尴尬,使得菜单感觉很脆弱。如果我的鼠标移动超出菜单 1 像素,菜单就会折叠消失。另一个问题是,只要鼠标悬停在菜单上,菜单就会打开。如果我在页面的一个部分移动鼠标移动到另一个部分,菜单就会快速打开和关闭,这可能会分散注意力和不可预期。

这是 jQuery 发挥作用并使事情变得更好更易用的好地方。

行动时间 — 使用 jQuery 改善下拉菜单

按照以下步骤,可以使用 jQuery 改善下拉菜单的可用性:

  1. 我们将从在 HTML 页面底部将 Superfish 插件连接到我们的文件中开始,放在 jQuery 和我们的scripts.js文件之间:

    <script src="img/jquery.js"></script>
    <script src="img/superfish.js"></script>
    <script src="img/scripts.js"></script>
    </body>
    </html>
    
    
  2. 接下来,打开scripts.js,我们将在其中编写调用superfish()方法的代码。像往常一样,我们将从文档准备语句开始,这样我们的脚本会在页面加载到浏览器中时立即运行:

    $(document).ready(function(){
    // Our code will go here.
    });
    
    
  3. 查看 Superfish 插件的文档,我们看到我们只需选择要应用行为的元素或元素,然后调用superfish()方法即可。在我们的ready()方法中,我们将添加以下代码:

    $(document).ready(function(){
    $('#sfNav').superfish();
    });
    
    

现在,如果您在浏览器中刷新页面,您会看到菜单看起来仍然很相似,但行为得到了很大改善。Superfish JavaScript 和 CSS 协同工作,为具有嵌套子菜单的菜单项添加箭头。如果将鼠标移开自菜单,它不会立即消失,这样可以将鼠标对角线移动到嵌套菜单项。当菜单项出现时,还会有一个微妙的淡入动画。当鼠标悬停时,每个菜单项的背景颜色会更改,使得当前活动项易于识别。

刚才发生了什么?

我们设置了一个导航菜单,由一组嵌套列表组成,形成一个层次结构。接下来,我们连接了一个 CSS 文件,为我们的菜单添加了简单的下拉功能。然而,纯 CSS 的菜单有一些缺陷。因此,我们连接了 Superfish 插件来解决这些问题,使我们的菜单更加用户友好。

垂直弹出式菜单

我们看到添加 Superfish 插件如何增强了我们下拉菜单的用户体验,但如果我们想要创建一个垂直的弹出式菜单呢?

行动时间 — 创建垂直弹出式菜单

从水平下拉菜单切换到垂直弹出菜单再简单不过了。我们将使用相同的 HTML 标记,我们的 JavaScript 代码也将保持不变。我们唯一需要做的改变是添加一些新的 CSS,使我们的菜单垂直显示而不是水平显示。我们可以继续使用上一个示例中使用的相同文件。

  1. 在 Superfish 下载的 css 文件夹中,你会找到一个名为 superfish-vertical.css 的文件。将该文件复制到你自己的 styles 文件夹中。在 HTML 文件的 head 部分,我们将附加新的 CSS 文件。在 superfish.cssstyles.css 之间,添加新的 CSS 文件:

    <link rel="stylesheet" href="styles/superfish.css"/>
    <link rel="stylesheet" href="styles/superfish-vertical.css"/>
    <link rel="stylesheet" href="styles/styles.css"/>
    
    
  2. 现在,在 HTML 中,我们将在包含菜单的列表中添加一个 sf-vertical 类。

    <ul id="sfNav" class="sf-menu sf-vertical">
    
    
  3. 现在当你在浏览器中刷新页面时,你将看到菜单垂直显示并带有弹出效果:进行操作的时间 —— 创建垂直弹出菜单

刚刚发生了什么?

水平下拉菜单和垂直弹出菜单之间唯一的区别是 CSS 和一个类名添加到菜单容器上。只需添加一个新的 CSS 文件和一个新的 CSS 类,就可以创建一个垂直弹出菜单,而不是水平下拉菜单。

自定义导航菜单

超级鱼插件附带的 CSS 使创建交互式导航菜单变得快速简单,但柔和的蓝色菜单不适合每种设计,所以让我们看看如何自定义菜单。

我们将看看如何通过编写自己的 CSS 来自定义菜单的外观,自定义显示嵌套菜单的动画,突出显示当前页面,并增强菜单的悬停行为。

我们将开始编写一些 CSS,为我们的菜单创建自定义外观。我们将使用 Suckerfish Dropdown 方法创建一个菜单,这将适用于我们网站访问者中没有启用 JavaScript 的用户。我想创建一个柔和的渐变背景,并使我的菜单项看起来像是漂浮在这个背景上的丝带。我的菜单将类似于以下截图:

自定义导航菜单

我要充分利用现代浏览器中可用的较新 CSS3 属性。我正在使用渐变、盒阴影和圆角。我精心选择了这些选项,因为即使没有这些额外的功能,菜单看起来仍然可以,而且可以使用。以下是菜单在旧版浏览器中的外观示例:

自定义导航菜单

你会注意到,与现代浏览器示例中的一些额外样式相比,它确实缺少了一些,但仍然完全可用并且通常令人满意。如果在所有浏览器中菜单看起来都一样很重要,那么我们可以使用图片而不是 CSS3 来获得最终效果。但是,我们可能需要添加一些额外的标记,并且肯定需要添加图像和额外的 CSS 行,所有这些都会增加页面的总体负担。是否决定让菜单在旧版浏览器中逐渐降级,或者是否决定编写额外的代码并创建额外的图像,使菜单在所有浏览器中看起来都一样,这是你需要根据客户的期望、网站的目标受众以及构建快速轻量级页面的重要性来做出的决定。

在为下拉菜单或弹出菜单编写自定义 CSS 时,请记住以下几点:

:hover 和 .sfHover

为了使菜单在没有 JavaScript 的情况下工作,你需要利用列表项的:hover 伪类。确保同时为相同元素创建一个带有 .sfHover 类的 CSS 选择器,这将被 JavaScript 使用。例如:

.sf-menu li.sfHover ul,
.sf-menu li:hover ul {
left: -1px;
top: 70px; /* match top ul list item height */
z-index: 99;
}

当鼠标悬停在父列表项上时,此段代码会使嵌套菜单在屏幕上可见。包括li:hover选择器确保菜单在没有 JavaScript 的情况下工作。同时包括li.sfHover选择器确保 JavaScript 菜单会应用相同的代码。

级联继承样式

CSS 的本质就是样式沿 DOM 层级进行级联,并应用于选择器的所有子元素以及选择器本身。因此,如果你编写代码来为一级菜单的列表项添加样式,如下所示:

ul.sf-menu li {
background: #cc0000; /* Dark red background */
}

你菜单中的所有 <li> 都将具有深红色背景,无论它们出现在菜单的哪个级别。如果你想为不同的菜单级别应用不同的样式,你需要在其他代码行中覆盖级联。例如,如果我想使第二级菜单具有深蓝色背景,我会在上述代码之后添加此段 CSS:

ul.sf-menu li li {
background: #0000cc; /* Dark blue background */
}

这意味着对于另一个<li>内部的<li>,背景将会是蓝色。请记住,现在这个样式将级联到其他菜单级别,所以如果你想要第三级菜单具有深绿色背景,你需要再添加一点 CSS:

ul.sf-menu li li li {
background: #00cc00; /* Dark green background */
}

在某些情况下,在你的 CSS 中使用直接后代选择器可以帮助你避免编写太多覆盖 DOM 中较高元素样式的 CSS。例如:

ul.sf-menu > li {
background: #cc0000; /* Dark red background */
}

这段 CSS 利用了直接后代选择器(>)。在这种情况下,深红色背景只会应用于具有 sf-menu类的

    直接嵌套的
  • ` 元素。它不会级联到第二级或第三级菜单。

    供应商前缀

    如果你想要尝试新的 CSS3 属性,你必须确保在属性前加上供应商特定的前缀。尽管这些属性受大多数现代浏览器支持,但它们仍在开发中,并且可能在不同浏览器中以稍微不同的方式实现。比如,下面这段 CSS,将底部两个角圆化的代码:

    .sf-menu ul li:last-child a {
    -webkit-border-bottom-right-radius: 7px;
    -webkit-border-bottom-left-radius: 7px;
    -moz-border-radius-bottomright: 7px;
    -moz-border-radius-bottomleft: 7px;
    border-bottom-right-radius: 7px;
    border-bottom-left-radius: 7px;
    }
    
    

    你可以看到,对于左下角和右下角的属性,在 Webkit 内核浏览器(主要是 Safari 和 Chrome)和 Mozilla 浏览器(主要是 Firefox)之间略有不同。在供应商特定代码之后,包括任何支持的浏览器的一般 CSS3 代码,以确保你的代码是未来兼容的。

    行动时间——定制 Superfish 菜单

    定制 Superfish 菜单主要涉及编写自己的 CSS 来样式化菜单,让它看起来更符合你的喜好。下面是我们将为菜单创建自定义外观的方法:

    如果你记得一些网页基础,你会记得 CSS 代表层叠样式表。层叠特性是我们在这里将要关注的。我们为菜单顶层编写的任何样式都将层叠到菜单的其他级别。我们必须记住这一点,并处理那些我们宁愿阻止样式层叠向下传递的情况。

    1. 让我们从样式化菜单的顶层开始。由于我使用了新的 CSS3 功能,我们需要准备写一些额外的代码,以便每个浏览器都能优雅地处理我们的代码。下面是我们将为菜单顶层创建的 CSS。将此代码放入你的styles.css文件中:

      /**** Level 1 ****/
      .sf-menu,
      .sf-menu * {
      list-style: none;
      margin: 0;
      padding: 0;
      }
      .sf-menu {
      background: #f6f6f6; /* Old browsers */
      background: -moz-linear-gradient(top, rgba(0,0,0,1) 1%, rgba(56,56,56,1) 16%, rgba(255,255,255,1) 17%, rgba(246,246,246,1) 47%, rgba(237,237,237,1) 100%); /* FF3.6+ */
      background: -webkit-gradient(linear, left top, left bottom, color-stop(1%,rgba(0,0,0,1)), color-stop(16%,rgba(56,56,56,1)), color-stop(17%,rgba(255,255,255,1)), color-stop(47%,rgba(246,246,246,1)), color-stop(100%,rgba(237,237,237,1))); /* Chrome,Safari4+ */
      background: -webkit-linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* Chrome10+,Safari5.1+ */
      background: -o-linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* Opera11.10+ */
      background: -ms-linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* IE10+ */
      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#ededed',GradientType=0 ); /* IE6-9 */
      background: linear-gradient(top, rgba(0,0,0,1) 1%,rgba(56,56,56,1) 16%,rgba(255,255,255,1) 17%,rgba(246,246,246,1) 47%,rgba(237,237,237,1) 100%); /* W3C */
      float: left;
      font-family: georgia, times, 'times new roman', serif;
      font-size: 16px;
      line-height: 14px;
      margin: 28px 0 14px 0;
      padding: 0 14px;
      }
      .sf-menu li {
      border-left: 1px solid transparent;
      border-right: 1px solid transparent;
      float: left;
      position: relative;
      }
      .sf-menu li.sfHover,
      .sf-menu li:hover {
      visibility: inherit; /* fixes IE7 'sticky bug' */
      }
      .sf-menu li.sfHover,
      .sf-menu li:hover {
      background: #DF6EA5;
      border-color: #a22361;
      -webkit-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
      -moz-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
      box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
      }
      .sf-menu a {
      border-left: 1px solid transparent;
      border-right: 1px solid transparent;
      color: #444;
      display: block;
      padding: 28px 14px;
      position: relative;
      width: 98px;
      text-decoration: none;
      }
      .sf-menu li.sfHover a,
      .sf-menu li:hover a {
      background: #DF6EA5;
      border-color: #fff;
      color: #fff;
      outline: 0;
      }
      .sf-menu a,
      .sf-menu a:visited {
      color: #444;
      }
      
      

      哎呀!这看起来像是很多代码,但其中大部分是我们需要为每种不同类型的浏览器使用的重复的渐变和阴影声明。让我们祈祷这个要求很快消失,浏览器供应商最终达成一致意见,确定用 CSS 创建渐变和阴影的方法。

    2. 接下来,让我们看看如何为我们菜单的下一级样式化。将以下 CSS 添加到你的styles.css文件中,以样式化第二级菜单:

      /***** Level 2 ****/
      .sf-menu ul {
      background: rgb(223,110,165); /* Old browsers */
      background: -moz-linear-gradient(top, rgba(223,110,165,1) 0%, rgba(211,54,130,1) 100%); /* FF3.6+ */
      background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(223,110,165,1)), color-stop(100%,rgba(211,54,130,1))); /* Chrome,Safari4+ */
      background: -webkit-linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* Chrome10+,Safari5.1+ */
      background: -o-linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* Opera11.10+ */
      background: -ms-linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* IE10+ */
      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#df6ea5', endColorstr='#d33682',GradientType=0 ); /* IE6-9 */
      background: linear-gradient(top, rgba(223,110,165,1) 0%,rgba(211,54,130,1) 100%); /* W3C */
      -webkit-border-bottom-right-radius: 7px;
      -webkit-border-bottom-left-radius: 7px;
      -moz-border-radius-bottomright: 7px;
      -moz-border-radius-bottomleft: 7px;
      border-bottom-right-radius: 7px;
      border-bottom-left-radius: 7px;
      border: 1px solid #a22361;
      border-top: 0 none;
      margin: 0;
      padding: 0;
      position: absolute;
      top: -999em;
      left: 0;
      width: 128px;
      -webkit-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
      -moz-box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
      box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
      font-size: 14px;
      }
      .sf-menu ul li {
      border-left: 1px solid #fff;
      border-right: 1px solid #fff;
      display: block;
      float: none;
      }
      .sf-menu ul li:last-child {
      border-bottom: 1px solid #fff;
      -webkit-border-bottom-right-radius: 7px;
      -webkit-border-bottom-left-radius: 7px;
      -moz-border-radius-bottomright: 7px;
      -moz-border-radius-bottomleft: 7px;
      border-bottom-right-radius: 7px;
      border-bottom-left-radius: 7px;
      }
      .sf-menu ul li:last-child a {
      -webkit-border-bottom-right-radius: 7px;
      -webkit-border-bottom-left-radius: 7px;
      -moz-border-radius-bottomright: 7px;
      -moz-border-radius-bottomleft: 7px;
      border-bottom-right-radius: 7px;
      border-bottom-left-radius: 7px;
      }
      .sf-menu li.sfHover li.sfHover,
      .sf-menu li:hover li:hover {
      -webkit-box-shadow: none;
      -moz-box-shadow: none;
      box-shadow: none;
      }
      .sf-menu li.sfHover li.sfHover {
      border-right-color: #cb2d79
      }
      .sf-menu li li a {
      border: 0 none;
      padding: 14px;
      }
      .sf-menu li li:first-child a {
      padding-top: 0;
      }
      .sf-menu li li.sfHover a,
      .sf-menu li li:hover a {
      background: transparent;
      border: 0 none;
      color: #f8ddea;
      outline: 0;
      }
      .sf-menu li li a:hover {
      color: #f8ddea;
      }
      .sf-menu li.sfHover li a,
      .sf-menu li:hover li a {
      background: transparent;
      }
      .sf-menu li.sfHover li.sfHover a {
      background: #cb2d79;
      }
      .sf-menu li.sfHover ul,
      .sf-menu li:hover ul {
      left: -1px;
      top: 70px; /* match top ul list item height */
      z-index: 99;
      }
      .sf-menu li li.sfHover,
      .sf-menu li li:hover {
      background: transparent;
      border-color: #fff;
      }
      
      

      再一次,这看起来像是很多 CSS,但我们仍然需要为每个单独的浏览器编写我们的声明。菜单的第二级项目也因需要覆盖或取消我们应用于菜单顶层但我们不希望应用于这里的任何样式而变得复杂。例如,我们为菜单顶层的所有项目应用了 float 属性,但我们需要取消第二级菜单的应用。

      我相信你开始明白为什么 Superfish 插件的大部分支持问题都与 CSS 有关,而不是 JavaScript。这里有很多要记住的东西。

    3. 最后,我们仍然有第三级菜单需要样式化。就像第二级一样,我们需要取消任何我们不希望应用的级联样式。将以下样式添加到你的styles.css文件中:

      /**** Level 3 ****/
      ul.sf-menu li.sfHover li ul,
      ul.sf-menu li:hover li ul {
      background: #cb2d79;
      top: -999em;
      -webkit-border-radius: 7px;
      -webkit-border-top-left-radius: 0;
      -moz-border-radius: 7px;
      -moz-border-radius-topleft: 0;
      border-radius: 7px;
      border-top-left-radius: 0;
      }
      ul.sf-menu li.sfHover li ul li,
      ul.sf-menu li:hover li ul li {
      background: transparent;
      border: 0 none;
      }
      ul.sf-menu li li.sfHover ul,
      ul.sf-menu li li:hover ul {
      left: 9em; /* match ul width */
      top: 0;
      }
      .sf-menu li.sfHover li.sfHover li a,
      .sf-menu li:hover li:hover li a {
      background: transparent;
      }
      .sf-menu li li li:first-child a {
      padding-top: 14px;
      }
      .sf-menu li li li a:hover {
      background: transparent;
      color: #fff;
      }
      /*** ARROWS ***/
      .sf-sub-indicator {
      display: none;
      }
      
      

    现在深吸一口气,因为我们终于到达了为菜单创建自定义样式的 CSS 的尽头。别担心,这是一个特别复杂的设计,使用了大量新的 CSS3 样式。如果你选择了一个稍微简单的东西,你将不得不创建更少的代码来使样式工作。

    这个 CSS 的额外好处是即使没有启用 JavaScript,它也可以工作。Superfish 插件只是增强了菜单,使其更易于使用。

    刚才发生了什么事?

    我们编写了自定义 CSS 来使我们的菜单与我们创建的设计匹配。为了正确地使悬停状态工作,我们必须记得同时为:hover伪类和.sfHover类设置样式。我们还必须深入研究 CSS 的级联特性,并决定哪些样式应该通过菜单的所有级别级联下来,哪些不应该。最后,我们必须记住,新的 CSS3 属性现在至少在不同的浏览器中必须以不同的方式声明。所有这些都导致下拉菜单需要比你最初预期的更多的自定义 CSS。只需耐心,一路下来时记住级联即可。

    自定义动画

    现在我们已经编写了自定义样式的 CSS,让我们来看看如何自定义显示子菜单的动画。滑动动画更适合我的菜单风格。默认动画是淡入子菜单,但我宁愿覆盖此默认行为,并用滑动动画替换它。

    行动时间 —— 合并自定义动画

    按照以下步骤将自定义动画合并到您的菜单中:

    1. 将菜单淡入意味着菜单的不透明度从 0 变化到 100 百分比。我宁愿动画化子菜单的高度,以便子菜单滑入视图。要做到这一点,打开你的 scripts.js 文件,我们将在 superfish() 方法内自定义动画值:

      $(document).ready(function(){
      $('#sfNav').superfish({
      animation: {height:'show'}
      });
      });
      
      

      在此处添加一个值将覆盖插件的默认行为,并用我们选择的动画替换它。

    2. 现在当你在浏览器中刷新页面时,你会看到子菜单滑入视图,而不是淡入,这是与我用来样式化菜单的 CSS 更匹配的动画。

    刚才发生了什么事?

    我们利用了 Superfish 插件的自定义选项之一,改变了嵌套子导航链接的显示动画。在 Superfish 菜单的文档中还涵盖了更多的自定义选项。

    hoverIntent 插件

    早些时候,我指出我们的菜单有一个问题,那就是菜单对mouseover事件的反应速度太快了。任何时候鼠标移动到菜单上,嵌套菜单就会打开。虽然这乍看起来可能是一件好事,但如果站点访问者只是在屏幕上移动鼠标,而不打算使用下拉或弹出式菜单,这可能会让人感到不安或惊讶。

    Superfish 插件内置支持 hoverIntent 插件。hoverIntent 插件有点暂停mouseover事件,并使页面等待以查看鼠标是否减速或停止在一个项目上,以确保这是站点访问者想要做的。这样,如果站点访问者碰巧将鼠标悬停在下拉菜单上,而在页面上寻找其他内容,子菜单不会开始出现,将其置于困惑中。

    如果你还记得的话,当我们下载 Superfish 插件时,hoverIntent 插件实际上已经包含在 ZIP 文件中。

    行动时间——添加 hoverIntent 插件

    按照以下步骤利用 hoverIntent 插件来为您的菜单增加功能:

    1. 在 Superfish 下载中,找到位于 js 文件夹内的 hoverIntent.js 文件,并将文件复制到您自己的 scripts 文件夹中。

    2. 接下来,我们需要将 hoverIntent 插件附加到我们的 HTML 页面上。

      提示

      不要忘记在将多个 JavaScript 文件附加到页面时考虑依赖关系。所有 jQuery 插件都依赖于 jQuery 来运行,因此需要在任何插件之前将 jQuery 附加到您的页面上。在这种情况下,Superfish 插件依赖于 hoverIntent 插件,因此我们需要确保在 Superfish 插件之前添加 hoverIntent。

    3. 将新的 <script> 标签添加到您的页面底部,与其他脚本一起如下:

      <script src="img/jquery.js"></script>
      <script src="img/hoverIntent.js"></script>
      <script src="img/superfish.js"></script>
      <script src="img/scripts.js">
      </script>
      </body>
      </html>
      
      

    现在,如果您在浏览器中刷新页面,您会发现当鼠标移动到菜单上时会有一个短暂的暂停,然后嵌套的子菜单出现。如果您快速将鼠标移到页面上,越过菜单,页面上不会出现不需要的子菜单。

    英雄般的尝试——设定你自己的速度

    尝试使用在文档中概述的 Superfish 插件的不同定制选项,调整显示子菜单的动画速度。

    摘要

    哇!刚刚我们做了很多工作,但我必须说,我们为我们的努力展示了一个相当令人印象深刻的导航菜单。我们学会了如何使用 Superfish jQuery 插件来生成水平下拉菜单或垂直飞出菜单。我们还学会了如何完全自定义我们菜单的外观和感觉,以完美适应我们的网站设计。能够隐藏站点的子部分直到需要它们,使得复杂的导航结构对于您的站点访问者来说不那么令人难以置信。可以清楚地看到站点的主要部分是什么,他们可以轻松地深入到他们想要的内容。

    接下来,我们将通过使用 Ajax 来进一步提升我们的动画效果。

    第七章:异步导航

    网站通常设置成,网站的所有页面共享一个通用的页眉和页脚,只有中间的内容从页面到页面发生改变。有时左侧和/或右侧的主要内容区域还有一个或多个侧边栏,在整个网站中保持不变。为什么让我们的网站访问者在浏览我们的网站时一遍又一遍地重新下载相同的页眉、页脚和侧边栏内容呢?

    在本章中,我们将涵盖以下主题:

    • 构建异步导航的网站

    • 增强异步导航以使其更加用户友好

    简单的异步导航

    在 Web 的早期,解决重复下载相同内容的问题的一个方法是框架。如果你对网页开发还太新,以至于不记得,框架提供了一种将单页面视图分割成几个不同的 HTML 文件的方法——浏览网站涉及重新加载一个或多个框架,而其他框架保持不变。框架有助于网站加载更快,使网站更容易维护,但最终它们制造的问题比解决的问题更多。有框架的网站易于破坏,搜索引擎难以索引,经常破坏前进和后退按钮,并且使访问者难以或无法收藏页面、分享链接或打印内容。由于所有这些问题,使用框架已不受青睐。

    近来,单页面应用程序开始变得更受欢迎。如果你登录你的 Twitter 账户并开始点击各处,你会注意到整个页面很少刷新——大部分交互发生在一个页面内。如果你访问 Gawker Media 网站中的任何一个,你会注意到在初始页面加载后,当你浏览网站时整个页面并不会再次刷新。现在,让我们看看如何以渐进增强的方式在我们自己的网站上实现相同类型的交互,以确保我们的网站在没有 JavaScript 的情况下仍然可以正常工作,并且可以被搜索引擎轻易索引。

    行动时间 — 建立一个简单的网站

    我们将开始建立一个小而简单的网站,其中包含一些页面。它们都共享相同的页眉、导航、侧边栏和页脚。它们都有一个主内容区,其中将显示每个页面的唯一内容。

    1. 通过建立一个包含所有相关文件和文件夹的index.html文件来开始,就像我们在第一章中所做的那样,设计师,遇见 jQueryindex.html文件的主体将包含我们的页眉、导航、侧边栏和页脚:

      <div id="ajax-header">
      <h1>Miniature Treats</h1>
      <ul id="ajax-nav">
      <li><a href ="index.html">Home</a></li>
      <li><a href ="cupcakes.html">Cupcakes</a></li>
      <li><a href ="petitfours.html">Petits Fours</a></li>
      <li><a href ="teacakes.html">Tea Cakes</a></li>
      <li><a href ="muffins.html">Muffins</a></li>
      </ul>
      </div>
      <div id="main-col">
      <div id="main-col-wrap">
      <p>Welcome to the miniature treats roundup. We've got a variety of miniature goodies to share with you.</p>
      <p>Don't be shy - just dive right in. Your mouth will water with the possibilites.</p>
      <p>If it's tiny enough to be a single portion all on it's own, we've included it here.</p>
      </div>
      </div>
      <div id="side-col">
      <div class="widget">
      <h4>More Information</h4>
      <ul>
      <li><a href="http://en.wikipedia.org/wiki/Cupcakes">Cupcakes (Wikipedia)</a></li>
      <li><a href="http://en.wikipedia.org/wiki/Petit_fours">Petits Fours (Wikipedia)</a></li>
      <li><a href="http://en.wikipedia.org/wiki/Tea_cake">Tea Cakes (Wikipedia)</a></li>
      <li><a href="http://en.wikipedia.org/wiki/Muffins">Muffins (Wikipedia)</a></li>
      </ul>
      </div>
      <div class="widget">
      <h4>Also Delicious</h4>
      <ul>
      <li><a href="http://en.wikipedia.org/wiki/Banana_bread">Banana Bread</a></li>
      <li><a href="http://en.wikipedia.org/wiki/Pumpkin_bread">Pumpkin Bread</a></li>
      <li><a href="http://en.wikipedia.org/wiki/Swiss_roll">Swiss Roll</a></li>
      <li><a href="http://en.wikipedia.org/wiki/Cheesecake">Cheesecake</a></li>
      <li><a href="http://en.wikipedia.org/wiki/Bundt_cake">Bundt Cake</a></li>
      </ul>
      </div>
      </div>
      <div id="ajax-foot">
      <p>Sample of progressively enhanced asynchronous navigation</p>
      </div>
      
      

      你可能会注意到额外的一个<div>,你可能没有预料到:main-colid 内的<div>,我添加了一个main-col-wrapid 的<div>标签。这并不用于布局或 CSS 目的,但一旦我们创建异步加载内容的 JavaScript 时,它就会被用到。

    2. 接下来,我们将编写一些 CSS 来创建一个简单的布局。打开您的styles.css文件并添加以下样式:

      #ajax-header { margin: 40px 0 0 0; }
      #ajax-header h1 { color:#859900;margin:0 0 10px 0;padding:0; }
      #ajax-nav { background:#859900;margin:0;padding:0;overflow:hidden;zoom:1; }
      #ajax-nav li { list-style-type:none;margin:0;padding:10px 20px;display:block;float:left; }
      #ajax-nav a,
      #ajax-nav a:link,
      #ajax-nav a:visited { color: #eee8d5; }
      #ajax-nav a:hover,
      #ajax-nav a:active { color: #fff; }
      #main-col { float:left;width:60%; }
      #side-col { float:right;width:35%; }
      .widget { border:2px solid #859900;margin:10px 0; }
      .widget h4 { margin:0 0 10px 0;padding:10px;background:#859900;color:#FDF6E3; }
      .float-right { float:right;margin:0 0 10px 10px; }
      .float-left { float:left;margin:0 10px 10px 0; }
      .source { font-size:12px; }
      #ajax-foot { clear:both;margin:10px 0 40px 0;padding:5px;background:#859900;color:#f3f6e3; }
      #ajax-foot p { margin:0;padding:0;font-size:12px;}
      
      

      最终页面将类似于以下屏幕截图:

      行动时间——设置一个简单的网站

      如果您感到灵感来了,请随意编写一些额外的 CSS 来使您的页面看起来更加花哨。

    3. 接下来,我们将创建网站的其他页面,即杯子蛋糕、小甜饼、茶点和松饼的页面。HTML 将与主页完全相同,除了<div>内部的内容,其idmain-col-wrap。以下是我为杯子蛋糕页面准备的内容样本:

      <div id="main-col-wrap">
      <h2>Cupcakes</h2>
      <p><img src="img/cupcakes.jpg" class="float-right" alt="Photo of cupcakes"/>A cupcake is a small cake designed to serve one person, frequently baked in a small, thin paper or aluminum cup. As with larger cakes, frosting and other cake decorations, such as sprinkles, are common on cupcakes.</p>
      <p>Although their origin is unknown, recipes for cupcakes have been printed since at least the late 18th century.</p>
      <p>The first mention of the cupcake can be traced as far back as 1796, when a recipe notation of "a cake to be baked in small cups" was written in <em>American Cookery</em> by Amelia Simms. The earliest documentation of the term <em>cupcake</em> was in "Seventy-five Receipts for Pastry, Cakes, and Sweetmeats" in 1828 in Eliza Leslie's <em>Receipts</em> cookbook.</p>
      <p class="source">Text source: <a href="http://en.wikipedia.org/wiki/Cupcakes">Wikipedia</a><br/>Image source: <a href="http://flickr.com/people/10506540@N07">Steven Depolo</a> via <a href="http://commons.wikimedia.org/wiki/File:Blue_cupcakes_for_graduation,_closeup_-_Tiffany,_May_2008.jpg">Wikimedia Commons</a></p>
      </div>
      
      

    在这个<div>之外,我的页面的其他部分与我们之前创建的主页完全相同。继续在类似的方式下创建松饼、茶点和小甜饼的页面,这样您就可以得到一个包含共享页眉、导航、侧边栏和页脚的五页网站。

    不要忘记,您的网站每页应在头部部分包含styles.css文件的链接,以及在文档底部,在结束</body>标记之前包含对 jQuery 和scripts.js文件的链接。

    刚才发生了什么?

    我们在 HTML 中设置了一个简单的五页网站。我们网站的每一页共享相同的页眉、导航、侧边栏和页脚。然后我们设置了一些简单的 CSS 来美化我们的页面。唯一表明这里会发生一些花哨的东西是额外的<div>包裹着我们的主内容区域——页面上包含从页面到页面不同内容的区域。

    行动时间——添加 Ajax 魔力

    如果您在浏览器中浏览这个简单的小网站,您会发现我们一遍又一遍地重新加载相同的页眉、导航、侧边栏和页脚。只有页面的主要内容区域的内容在页面之间不断地变化。让我们使用 jQuery 的魔力来解决这个问题。

    1. 只是一个提醒,除非您的页面是由服务器提供的,否则这些 Ajax 函数将不起作用。要看这段代码的实际效果,您要么需要将页面上传到服务器,要么在自己的计算机上创建一个服务器。首先,我们将打开我们的scripts.js文件并开始编写我们的代码。我们将像往常一样以文档就绪语句开始:

      $(document).ready(function(){
      // Our code will go here
      });
      
      
    2. 我们需要选择导航中的所有链接。这看起来类似于这样:

      $(document).ready(function(){
      $('#ajax-nav a')
      });
      
      
    3. 当用户点击这些链接时,浏览器会加载请求的页面。这就是我们希望覆盖的行为,因此我们将绑定一个函数到链接,覆盖链接的点击行为如下:

      $(document).ready(function(){
      $('#ajax-nav a').bind('click', function(){
      // Our clicky code goes here
      });
      });
      
      
    4. 当站点访问者单击链接时,我们需要做的第一件事情就是取消默认行为。我们可以通过告诉函数返回false来实现:

      $(document).ready(function(){
      $('#ajax-nav a').bind('click', function(){
      return false;
      });
      });
      
      

      现在,如果您在浏览器中重新加载您的简单网站,您会发现单击主导航中的链接没有任何作用。您请求的页面不再加载到浏览器中。我们已经为我们自己的代码做好了准备。

    5. 如果我们要从服务器获取页面,我们需要知道我们要获取哪个页面。我们需要知道我们需要调用哪个 URL。幸运的是,我们的链接已经在它们的href属性中包含了这些信息,例如,通过查看我们杯子蛋糕链接的 HTML:

      <a href ="cupcakes.html">Cupcakes</a>
      
      

      我们可以看到我们需要请求以获取有关杯子蛋糕信息的页面是cupcakes.html。

      我们将使用 jQuery 来获取刚刚点击的链接的href属性:

      $(document).ready(function(){
      $('#ajax-nav a').bind('click', function(){
      var url = $(this).attr('href');
      return false;
      });
      });
      
      

      现在我们有一个名为url的变量,其中包含了刚刚点击的链接的href属性。记住,变量只是容器。如果我们的网站访问者刚刚点击了杯子蛋糕链接,那么url变量将包含cupcakes.html。而另一方面,如果网站访问者刚刚点击了松饼链接,那么url变量将包含muffins.html。这个函数在站点访问者点击主导航中的任何链接时都会被调用- $(this)将始终引用刚刚点击的链接。

    6. 现在我们知道服务器上的哪个页面包含了网站访问者请求的信息,那么我们该怎么办?幸运的是,jQuery 为我们提供了load()方法,它可以轻松地将内容从服务器加载到我们的页面中。我们将选择页面上我们想要加载内容的元素,然后调用那个元素的load()方法。在这种情况下,我们将选择<div>标签,并且其idmain-col,因为这是页面上从一页到另一页变化的内容的容器:

      $(document).ready(function(){
      $('#ajax-nav a').bind('click', function(){
      var url = $(this).attr('href');
      $('#main-col').load();
      return false;
      });
      });
      
      
    7. 如果您刷新浏览器中的页面并点击主导航中的链接,您将会发现没有任何反应。浏览器没有报告任何错误,那么问题出在哪里呢?

      记得 Maggie 这只狗吗,她在第一章 设计师,见识 jQuery中正在吃培根。Maggie 有一个这样的eat方法:

      Maggie.eat();
      
      

      然而,请记住,她不能只是吃东西——她必须吃一些东西。因此,我们将bacon传递给 Maggie 的eat()方法如下:

      Maggie.eat('bacon');
      
      

      load方法也类似。我们不能只是加载—我们必须加载一些东西。在这种情况下,我们知道我们需要加载什么—url 变量中包含的 URL 中的内容:

      $(document).ready(function(){
      $('#ajax-nav a').bind('click', function(){
      var url = $(this).attr('href');
      $('#main-col').load(url);
      return false;
      });
      });
      
      

      现在,如果刷新浏览器并尝试点击主导航中的杯子蛋糕链接,您会看到杯子蛋糕页面的内容确实加载到我们的#main-col div 中。然而,这并不是我们想要的,因为它加载整个页面:

      行动时间- 添加 Ajax 魔法

    8. 我们不想获取整个页面。我们只需要#main-col div 中的内容,这就是额外的包装元素<div>idmain-col-wrap的地方。我们可以告诉 jQuery 仅将<div>和其内容加载到#main-col <div>中,如下所示:

      $(document).ready(function(){
      $('#ajax-nav a').bind('click', function(){
      var url = $(this).attr('href');
      $('#main-col').load(url + ' #main-col-wrap');
      return false;
      });
      });
      
      

      这有时被称为 jQuery 的部分加载方法,因为我们不是将获取到的整个内容加载到页面中,而只是我们关心的部分。如果你在浏览器中刷新页面并点击主导航,你会发现现在内容按我们预期的方式加载,只有页面的主内容区域刷新。页眉、导航、侧边栏和页脚仍然保留在页面上,而主内容区域重新加载。

    刚刚发生了什么?

    我们使用了 jQuery 强大的基于 CSS 的选择器来选择主导航中的所有链接。我们确定了链接的点击行为是我们需要覆盖以获得所需结果的行为。我们将一个点击函数绑定到链接上,每次调用链接时都会运行。我们取消了链接在浏览器窗口中加载新页面的默认行为。接下来,我们检查链接以获取href属性中包含的 URL。我们选择了页面上希望加载新内容的容器,并使用 jQuery 的load()方法调用所需内容。我们向load()方法传递了一个选择器和 URL,以便 jQuery 知道我们只想加载选定元素中的内容,而不是整个页面。

    我们将我们简单的网站转换成了单页面应用。我们使用渐进增强的方式来做到这一点,这样那些没有启用 JavaScript 的网站访问者也可以无问题地使用我们的网站。搜索引擎也可以索引我们网站的内容。而这一切都只用了几行 JavaScript 代码 —— 多亏了 jQuery!

    豪华异步导航

    你会对自己只用几行代码就将一个普通网站变成单页面应用而感到非常满意,但让我们面对现实:我们简单的异步导航还有待改进,绝对需要一些润色。

    或许最明显的是,我们破坏了浏览器的后退和前进按钮。我们不能再使用它们在我们网站的页面之间导航。我们还剥夺了我们网站访问者将页面链接加为书签或分享的能力。我们在我们的主导航中点击链接后,也没有向我们的网站访问者提供任何反馈。由于我们的页面短小简单,它们通常会很快加载,但互联网在速度方面众所周知是不可预测的。有时加载我们的内容可能需要半秒、一秒或更长时间 —— 我们的网站访问者不知道他们的浏览器正在努力获取新内容 —— 它看起来就像什么都没发生。

    还有一些其他小技巧,可以使整个过程更加美观和快速,所以让我们开始制作高级异步导航的豪华版本吧。

    行动时间 —— 构建豪华异步导航

    为了给我们的异步导航添加一些缺失的功能,我们将使用 Ben Alman 的出色的 jQuery BBQ 插件。尽管这个名字可能会让你觉得饥饿,但在这种情况下,BBQ 代表 Back Button 和 Query。我们将继续使用我们在上一个示例中创建的文件。

    1. 首先,我们需要获取 BBQ 插件的副本以进行使用。访问 benalman.com/projects/jquery-bbq-plugin/ 获取下载文件以及 jQuery BBQ 插件的文档和示例。行动时间——构建豪华的异步导航

      和往常一样,我们将下载插件的压缩版本,并将其放入我们的scripts文件夹中,与 jQuery 和我们的scripts.js文件并列。

      行动时间——构建豪华的异步导航

    2. 接下来,打开你的迷你网站的每个 HTML 页面,并在 jQuery 之后、scripts.js之前添加 BBQ 插件:

      <script type="text/javascript" src="img/jquery.js"></script>
      <script type="text/javascript" src="img/jquery.ba-bbq.min.js"></script>
      <script type="text/javascript" src="img/scripts.js"></script>
      </body>
      </html>
      
      

    现在我们已经准备好开始构建我们的异步导航的豪华版本了。

    刚刚发生了什么?

    我们下载了 jQuery BBQ 插件,并将其附加到我们的每个页面上。到目前为止,这在我们的网站上没有任何区别——我们已经附加了 BBQ 插件,但我们并没有使用它来做任何事情。接下来,我们将看看如何使用 BBQ 插件。

    行动时间——使用 BBQ 插件

    我们的第一项任务是让返回和前进按钮起作用,并允许我们的网站访问者将链接添加到书签并分享到个别页面。这就是为什么我们包含了 jQuery BBQ 插件。

    1. 我们将编写一些新的 JavaScript 代码,因此将scripts.js中我们之前编写的代码清除,并用以下简单的文档就绪语句替换它:

      $(document).ready(function(){
      // Our deluxe ajaxy code goes here
      });
      
      
    2. 接下来,我们将选择主导航中的每个链接,并用哈希链接替换 URL,以便浏览器认为它们是我们 HTML 页面内部的链接。

      $(document).ready(function(){
      $('#ajax-nav a').each(function(){
      $(this).attr('href', '#' + $(this).attr('href'));
      });
      });
      
      

      我们选择主导航中的所有链接,然后循环遍历它们以在 URL 前添加一个#字符。例如,cupcakes.html链接现在是#cupcakes.html。如果你在浏览器中刷新页面,你会发现点击链接不会改变页面上的任何内容,但它会更新浏览器位置栏中的哈希。

      行动时间——使用 BBQ 插件

    3. 接下来,我们将一个函数绑定到窗口的hashchange事件上。现代浏览器提供了一个称为hashchange的事件,每当 URL 的哈希更改时就会触发,就像当您单击主导航链接时所做的那样。旧版浏览器不支持hashchange事件,但这就是 jQuery BBQ 插件发挥作用的地方。它在大多数浏览器中提供了对伪hashchange事件的支持,这样我们只需编写我们的代码一次,而不必担心浏览器的差异。这是我们如何将函数绑定到hashchange事件上的方式:

      $(document).ready(function(){
      $('#ajax-nav a').each(function(){
      $(this).attr('href', '#' + $(this).attr('href'));
      });
      $(window).bind('hashchange', function(e) {
      // our function goes here
      });
      });
      
      
    4. 我们编写的函数现在将在窗口的哈希更改时调用,我们知道每当站点访问者点击我们的主导航中的链接时都会发生这种情况。现在我们可以编写代码,告诉浏览器在发生这种情况时该做什么。

      $(document).ready(function(){
      $('#ajax-nav a').each(function(){
      $(this).attr('href', '#' + $(this).attr('href'));
      });
      $(window).bind('hashchange', function(e) {
      var url = e.fragment;
      $('#main-col').load(url + ' #main-col-wrap');
      });
      });
      
      

      首先,我们设置一个名为url的变量,并将其设置为e.fragmentfragment属性由 jQuery BBQ 插件提供。它等于 URL 的哈希但不包括哈希符号。因此,如果窗口的哈希更改为#cupcakes.htmle.fragment将等于cupcakes.html

      下一行代码与我们的基本 Ajax 导航示例相同。我将选择页面上要加载内容的容器,然后调用load()方法。我将传递 URL 和 jQuery 选择器,指定要加载到浏览器中的页面部分。

      如果你现在在浏览器中刷新页面,你会看到我们的主导航再次以异步方式工作。点击链接只会加载页面的主内容区域,而其余部分保持不变。然而,有一个重要的区别——如果你点击回退和前进按钮,它们会起作用。一旦你点击进入杯子页面,你可以点击返回按钮返回首页。

    5. 我们只剩下一件事要做,就是确保我们的站点访问者可以收藏和分享我们页面的链接。如果你点击杯子页面,复制浏览器地址栏中的 URL,并打开一个新的浏览器窗口或一个新的选项卡,并粘贴 URL,你会发现你得到的是站点的主页而不是杯子页面。如果你查看 URL,#cupcakes.html哈希就在那里,我们只需要告诉我们的代码去找它。最简单的方法是在页面加载时立即触发窗口的hashchange事件。以下是我们如何做到的:

      $(document).ready(function(){
      $('#ajax-nav a').each(function(){
      $(this).attr('href', '#' + $(this).attr('href'));
      });
      $(window).bind('hashchange', function(e) {
      var url = e.fragment;
      $('#main-col').load(url + ' #main-col-wrap');
      });
      $(window).trigger('hashchange');
      });
      
      

      现在,你可以在新窗口中打开杯子链接,你会看到杯子页面加载,就像它应该的那样。我们的hashchange函数在页面加载时立即触发,加载正确的内容。

    刚刚发生了什么事?

    我们使用 jQuery 循环遍历我们的每个导航链接,并用内部链接或哈希链接替换它们。为什么不直接在 HTML 中这样做呢?因为我们想确保我们的页面继续为禁用 JavaScript 的用户工作。

    然后,我们使用 jQuery BBQ 插件将我们的异步导航更改为启用书签和共享链接以及浏览器中的后退和前进按钮。这使得我们的站点能够像单页应用程序一样运行,而不会破坏站点访问者的预期体验。

    行动时间——在导航中突出显示当前页面

    我们已经使我们的异步导航比我们简单的示例好得多,但我认为我们可以继续努力,使它变得更好。接下来,我们将突出显示导航中当前正在查看的页面,以便我们的网站访问者轻松看到他们所在的页面。

    行动时间——在导航中突出显示当前页面

    1. 首先,让我们再次打开styles.css并编写导航的.currentCSS 类:

      #ajax-nav li.current{ background:#a3bb00; }
      
      

      我已经将我的导航栏设为绿色,所以我要将.current类设为稍浅一些的绿色,以便当前项目在菜单中突出显示。你可以参考我的示例或创建自己的样式——任何适合你口味的都可以。

    2. 现在我们只需要将我们的.current类应用到当前导航项上。我们将在之前编写的hashchange事件函数中添加几行代码。我们将从检查窗口位置是否有哈希开始:

      $(document).ready(function(){
      $('#ajax-nav a').each(function(){
      $(this).attr('href', '#' + $(this).attr('href'));
      });
      $(window).bind('hashchange', function(e) {
      var url = e.fragment;
      $('#main-col').load(url + ' #main-col-wrap');
      if (url) {
      // The code if there is a hash
      } else {
      // The code if there is not a hash
      }
      });
      $(window).trigger('hashchange');
      });
      
      
    3. 现在,如果有一个哈希值,那么我们想要找到与哈希值对应的主导航中的链接,找到它的父容器,并添加当前类。听起来有点复杂,但我可以用一行代码完成:

      $(window).bind('hashchange', function(e) {
      var url = e.fragment;
      $('#main-col').load(url + ' #main-col-wrap');
      $('#ajax-nav li.current').removeClass('current');
      if (url) {
      $('#ajax-nav a[href="#' + url + '"]').parents('li').addClass('current');
      } else {
      // The code if there is not a hash
      }
      });
      
      

      我正在使用 jQuery 强大的属性选择器来选择具有href属性等于窗口哈希的链接。然后我使用parents()方法获取链接的父级。我将li传递给parents()方法,告诉 jQuery 我只对一个父级感兴趣,即包含我的链接的<li>。然后我使用addClass()方法将我的当前类添加到当前链接中。

    4. 如果没有哈希值,那么我想要突出显示主页,这是我们主导航中的第一个页面。我会选择第一个<li>并添加当前类,如下面的代码所示:

      $(window).bind('hashchange', function(e) {
      var url = e.fragment;
      $('#main-col').load(url + ' #main-col-wrap');
      $('#ajax-nav li.current').removeClass('current');
      if (url) {
      $('#ajax-nav a[href="#' + url + '"]').parents('li').addClass('current');
      } else {
      $('#ajax-nav li:first-child').addClass('current');
      }
      });
      
      
    5. 现在,如果你在浏览器中刷新页面并浏览页面,你会看到当前页面被突出显示,但随着你在网站上移动,越来越多的导航被突出显示——我们在添加新突出显示之前没有删除旧的突出显示。我们将添加以下代码以在添加新的突出显示之前删除当前突出显示:

      $(window).bind('hashchange', function(e) {
      var url = e.fragment;
      $('#main-col').load(url + ' #main-col-wrap');
      $('#ajax-nav li.current').removeClass('current');
      if (url) {
      $('#ajax-nav a[href="#' + url + '"]').parents('li').addClass('current');
      } else {
      $('#ajax-nav li:first-child').addClass('current');
      }
      });
      
      

    在浏览器中刷新页面,你会看到突出显示现在正常工作,只突出显示当前页面。

    刚刚发生了什么?

    我们在我们的hashchange函数中添加了几行代码,以在导航中为当前页面添加高亮显示。这将帮助网站访问者在网站上定位自己的位置,并进一步加强他们当前的位置感。

    行动时间——添加加载动画

    接下来,我们想要向网站访问者显示,当他们点击导航中的链接时,有一些事情正在发生。请记住,如果来自服务器的响应速度很慢,网站访问者看不到任何事情正在发生。即使浏览器正在努力获取新页面的内容,网站访问者也没有任何指示表明有任何事情正在发生。让我们添加一个小动画,以明显地显示我们页面上正在发生的事情。

    加载动画可以采用许多不同的形式:旋转的雏菊、动画进度条、闪烁的点 —— 任何能传达正在进行的操作的东西都将有助于使您的站点对于您的站点访问者感觉更加迅捷和响应。

    操作时间 — 添加加载动画

    1. 首先,前往ajaxload.info来创建并下载您选择的加载动画。操作时间 — 添加加载动画

    2. 生成器框中选择类型、背景颜色和前景颜色,然后单击生成!按钮。

    3. 预览框中,您将看到您按钮的预览以及下载按钮的链接。单击下载!链接以下载您刚创建的加载动画的副本。

    4. 当你下载了按钮之后,将它放入你的images文件夹,与你网站上使用的其他图片一起。

    5. 现在,让我们仔细考虑一下我们需要对页面进行的修改。我们希望淡出当前显示在#main-col div 中的内容,并在其位置显示我们的加载动画,直到服务器发送回我们新页面的内容。一旦我们收到了那个内容,我们就想隐藏加载动画并显示内容。

      当我们准备向我们的站点访问者显示加载动画时,我们希望它立即可见。如果我们不得不从服务器获取图像,那将毫无意义 —— 实际页面内容可能在我们的图像之前返回。所以我们必须预加载图像。使用 jQuery,这非常简单。一旦文档加载到浏览器中,我们将创建一个新的图像元素,如下所示:

      $(document).ready(function(){
      var loadingImage = $('<img src="img/ajax-loader.gif"/>');
      $('#ajax-nav a').each(function(){
      ...
      
      

      只创建此元素就足以将图像预加载到浏览器的缓存中。现在,当我们准备显示图像时,它将立即可用,无需等待。

    6. 接下来,我们必须编写一些 CSS 来处理我们的加载图像的显示方式。我们将其包装在一个简单的段落标签中,然后添加一些填充并使图像居中:

      #loading { padding:20px;text-align:center;display:none; }
      
      
    7. 请注意,我们还将display设置为none—这样我们在准备好之前就不会有图像显示出来。我们只希望我们的动画出现在 URL 中有一个哈希时,所以在我们的if/else语句内,我们将加载动画附加到#main-col div 中:

      ...
      if (url) {
      $('#main-col').append('<p id="loading"></p>')
      $('#loading').append(loadingImage);
      $('#ajax-nav a[href="#' + url + '"]').parents('li').addClass('current');
      } else {
      ...
      
      

      我们已经在文档中添加了一个idloading的段落,并将我们预加载的加载图像附加到该段落中。请记住,即使它存在,由于我们用 CSS 隐藏了它,所以它还不可见。

    8. 接下来,我们将淡出当前在页面上显示的内容。如果我们的内容从服务器返回得很快,我们要确保我们没有妨碍,所以我们会告诉动画快速完成:

      ...
      if (url) {
      $('#main-col').append('<p id="loading"></p>')
      $('#loading').append(loadingImage);
      $('#ajax-nav a[href="#' + url + '"]').parents('li').addClass('current');
      $('#main-col-wrap').fadeOut('fast');
      } else {
      ...
      
      
    9. 最后,我们想要展示我们的加载动画,但我们不想让它在内容淡出之前出现。为了确保它在此之前不会出现,我们将它作为回调函数添加到 fadeOut() 方法中。回调函数是在动画完成后调用的函数。这是我们如何向 fadeOut() 方法添加回调函数的方式:

      ...
      if (url) {
      $('#main-col').append('<p id="loading"></p>')
      $('#loading').append(loadingImage);
      $('#ajax-nav a[href="#' + url + '"]').parents('li').addClass('current');
      $('#main-col-wrap').fadeOut('fast', function(){
      $('#loading').show();
      });
      } else {
      ...
      
      

      现在,当网站访问者点击链接时,定位栏中的哈希将更新。这将触发我们的代码,将页面当前内容淡出,显示加载动画,然后一旦服务器返回新页面内容,立即将加载动画替换为新页面内容。如果您非常幸运,您的网站访问者甚至不会有机会看到加载动画,因为您的服务器会快速返回新页面内容。但是,如果任何地方出现了减速,您的网站访问者将收到一个清晰的信息,表明正在发生某些事情,他们不会感到困惑或感到您的网站缓慢且不响应。

    刚才发生了什么?

    我们为网站访问者添加了一些动画效果,以示在服务器响应新页面内容的过程中出现超过几分之一秒的延迟时发生了什么。网站访问者将立即看到内容淡出,并且加载动画会取而代之,直到服务器响应新页面内容为止。

    如果您正在使用 WAMP 或 MAMP 从本地计算机查看页面,那么新内容很可能会返回得非常快,以至于您没有机会看到加载动画。但是,如果您将页面上传到服务器并通过互联网访问它们,则几乎可以肯定会在浏览器获取新内容时至少看到加载动画的一小部分。

    总结

    在本章中,我们学习了如何建立一个简单的网站,然后我们增强了它的功能,使其表现得像一个单页面应用程序,但不会对搜索引擎或禁用 JavaScript 的网站访问者造成影响。首先,我们建立了一个简单版本,可能适用于某些简单情况。然后,我们看了看如何设置豪华版本,它允许收藏和分享链接,工作的前进和后退按钮,导航中当前页面的突出显示,以及平滑的过渡动画,向网站访问者展示浏览器正在辛勤工作。所有这些都相对简单和直接,多亏了 jQuery 和 jQuery BBQ 插件。

    接下来,我们将研究如何将内容加载到灯箱中。

    第八章:在灯箱中显示内容

    在网上经常看到以灯箱形式展示照片图库已经变得很普遍了。灯箱还可以用于其他用途 — 播放视频、显示附加信息、向网站访问者显示重要信息,甚至显示其他网站。在本章中,我们将介绍如何使用灵活且适应性强的 Colorbox 插件为各种用途创建灯箱。

    在本章中,我们将介绍如何使用 Colorbox 插件来:

    • 创建一个简单的相册

    • 自定义相册设置

    • 构建一个花哨的登录框

    • 播放一系列视频

    • 创建一个单页网站作品集

    简单相册

    简单相册可能是使用灯箱最常见的用途之一。我们将设置一个页面,显示每张照片的缩略图,并在点击缩略图时在灯箱中显示全尺寸图像。要开始,请准备一系列带有每个缩略图的较小尺寸的照片。

    这是一个在灯箱中显示的照片的示例:

    简单相册

    操作时间 — 设置简单相册

    我们将使用 Colorbox 插件创建一个简单的相册,我们将逐步进行:

    1. 我们将开始设置一个基本的 HTML 页面和相关文件和文件夹,就像我们在 第一章 中所做的那样,设计师,见到 jQuery。HTML 文档的主体将包含缩略图列表:

      <ul class="thumb-list">
      <li><a href="images/abandoned-house.jpg" title="Old Abandoned House" rel="ireland"><img src="img/ abandoned-house.jpg" alt="Abandoned House"/></a></li>
      <li><a href="images/cemetary.jpg" title="Celtic Cemetary with Celtic Crosses" rel="ireland"><img src="img/cemetary.jpg" alt="Celtic Cemetary"/></a></li>
      <li><a href="images/cliffs-of-moher.jpg" title="Cliffs of Moher" rel="ireland"><img src="img/cliffs-of-moher.jpg" alt="Cliffs of Moher"/></a></li>
      <li><a href="images/dublin.jpg" title="River Liffey in Dublin" rel="ireland"><img src="img/dublin.jpg" alt="Dublin"/></a></li>
      <li><a href="images/dun-aonghasa.jpg" title="Dun Aonghasa on Inis More" rel="ireland"><img src="img/dun-aonghasa.jpg" alt="Dun Aonghasa"/></a></li>
      <li><a href="images/falling-in.jpg" title="Warning Sign" rel="ireland"><img src="img/falling-in.jpg" alt="Falling In"/></a></li>
      <li><a href="images/guagan-barra.jpg" title="Guagan Barra" rel="ireland"><img src="img/guagan-barra.jpg" alt="Guagan Barra"/></a></li>
      <li><a href="images/inis-more.jpg" title="Stone Fences on Inis More" rel="ireland"><img src="img/inis-more.jpg" alt="Inis More"/></a></li>
      <li><a href="images/inis-more2.jpg" title="Cliffs on Inis More's West Coast" rel="ireland"><img src="img/inis-more2.jpg" alt="Inis More Too"/></a></li>
      <li><a href="images/inis-more3.jpg" title="Inis More Fence" rel="ireland"><img src="img/inis-more3.jpg" alt="Inis More Three"/></a></li>
      <li><a href="images/mizen-head.jpg" title="Crashing Waves Near Mizen Head" rel="ireland"><img src="img/mizen-head.jpg" alt="Mizen Head"/></a></li>
      <li><a href="images/obriens-tower.jpg" title="O'Brien's Tower at the Cliffs of Moher" rel="ireland"><img src="img/obriens-tower.jpg" alt="O'Brien's Tower"/></a></li>
      <li><a href="images/random-castle.jpg" title="Some Random Castle" rel="ireland"><img src="img/random-castle.jpg" alt="Random Castle"/></a></li>
      <li><a href="images/turoe-stone.jpg" title="Turoe Stone" rel="ireland"><img src="img/turoe-stone.jpg" alt="Turoe Stone"/></a></li>
      </ul>
      
      

      请注意,我们将每个缩略图都包装在到图像全尺寸版本的链接中。如果在浏览器中加载页面,你会看到页面适用于禁用 JavaScript 的用户。点击缩略图会在浏览器中打开全尺寸图像。点击后退按钮会返回到相册。

      请注意,我们还在每个链接上包含了一个 title 属性。对于我们的网站访问者来说,这对他们很有帮助,因为当他们用鼠标悬停在缩略图上时,它将显示图像的简短描述。但是稍后也将用于 Colorbox 插件。我们还在每个链接上包含了一个 rel 属性,并将其设置为 ireland。这将使我们在准备添加 Colorbox 插件魔法时很容易选择我们的爱尔兰图像组。

    2. 接下来,我们将添加一些 CSS 来将图像布局在网格中。打开你的 styles.css 文件并添加这些样式:

      ul.thumb-list { margin:20px 0;padding:0;text-align:center; }
      ul.thumb-list li { margin:0;padding:0;display:inline-block; }
      
      

      操作时间 — 设置简单相册

      如果你愿意的话,可以随意调整一下 CSS,为你的图片缩略图创建不同的布局。

    3. 现在,让我们添加 jQuery 魔法。我们将使用 Color Powered 的 Colorbox 插件。请前往 jacklmoore.com/colorbox 查找下载、文档和演示。你会在下载部分找到下载链接,在页面顶部附近。只需点击当前版本号下载 ZIP 文件。操作时间 — 设置简单相册

    4. 解压缩文件夹并查看其内容。你会找到插件脚本文件本身,当然还有许多其他好东西。行动时间——设置简单的照片库

      插件代码本身位于colorbox文件夹中——你会找到开发和压缩版本。五个示例文件夹中每个都包含一个示例文件(index.html),展示了插件的作用。为什么有五个不同的文件夹?每个文件夹包含相同的基本示例,但 Colorbox 有五种不同的外观。这些相同的示例可以在 Colorbox 网站上点击网站上查看演示部分中的数字来查看。

      开箱即用,插件的开发人员为我们提供了五种不同的 Colorbox 外观和感觉的可能性。如果这还不够选择,他们还包含了一个包含用于创建这五种不同外观的所有图像资产的colorbox.aiAdobe Illustrator)文件。您可以随心所欲地自定义它们,然后从 Illustrator 中导出您的新完全自定义外观,以创建您自己的外观。更改颜色和特效非常简单,但请记住,如果更改图像资产的大小和形状,您将不得不修改相应的 CSS 文件以适应新的大小。

    5. 尝试每个不同的示例,无论是在网站上还是使用 ZIP 下载中包含的示例文件,并注意外观、大小、前进和后退按钮的位置、关闭按钮、标题、分页指示器(图像 1/3)等都是通过 CSS 而不是插件代码本身控制的。这使得定制外观和感觉非常容易——所有这些都是通过 CSS 而不是 JavaScript 完成的。

    6. 在 ZIP 下载中,在colorbox文件夹中,你会找到插件代码一个名为jquery.colorbox-min.js的文件。将此文件复制到你自己的scripts文件夹中。

    7. 我们将从选择提供的 CSS 外观中开始。选择你喜欢的外观,然后将其 CSS 文件复制粘贴到你自己的styles文件夹中。打开该 CSS 外观的images文件夹,并将该文件夹中的图像复制粘贴到你自己的images文件夹中。一旦你选择了一个外观,你自己的设置应该如下所示:行动时间——设置简单的照片库

      index.html文件包含了链接到全尺寸版本的缩略图图像的 HTML。images文件夹包含了与我选择的 Colorbox 外观提供的图像以及我的幻灯片秀的自己的图像,包括缩略图和全尺寸版本。我的scripts文件夹包含了 jQuery(jquery.js)和 Colorbox 插件脚本(jquery.colorbox-min.js)。我的styles文件夹包含了我选择的 Colorbox 外观的 CSS 文件。

    8. 我们必须打开 colorbox.css 进行一组微小的编辑。在示例文件中,CSS 文件不在 stylescss 文件夹中,而是与 index.html 文件一样位于顶层。我们选择遵循我们的首选约定,并将我们的 CSS 存储在我们的 styles 文件夹中。这意味着我们将不得不打开 colorbox.css 文件并更新 CSS 中的图像引用。我将不得不替换以下引用:

      #cboxTopLeft{width:21px; height:21px; background:url(images/controls.png) no-repeat -100px 0;}
      
      

      具有以下引用:

      #cboxTopLeft{width:21px; height:21px; background:url(../images/controls.png) no-repeat -100px 0;}
      
      

      我只是告诉 CSS 向上一级查找,然后查找 images 文件夹。您应该可以通过使用文本编辑器的查找和替换功能快速替换所有这些内容。

    9. 接下来,打开您的 index.html 文件,并在您自己的 styles.css 之前的 head 部分附加 colorbox.css 文件:

      <head>
      <title>Chapter 8: Showing Content in Lightboxes</title>
      <link rel="stylesheet" href="styles/colorbox.css"/>
      <link rel="stylesheet" href="styles/styles.css"/>
      </head>
      
      
    10. 然后,在文件底部,在关闭</body>标签之前,将 Colorbox 插件附加在 jQuery 之后,但在您自己的 scripts.js 文件之前:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.colorbox-min.js"></script>
      <script src="img/scripts.js"></script>
      
      
    11. 现在,记住我们在每个链接上包含的 rel="ireland" 属性吗?我们将在 JavaScript 中使用它来选择 Colorbox 插件的所有爱尔兰图片链接。打开您的 scripts.js 文件,并在文档就绪语句中编写属性选择器,以选择具有 rel 属性等于 ireland 的所有链接:

      $(document).ready(function(){
      $('a[rel="ireland"]')
      });
      
      
    12. 唯一剩下的事情就是在这些链接上调用 colorbox() 方法,Colorbox 插件会为我们处理其他所有事情:

      <script type="text/javascript">
      $('a[rel="ireland"]').colorbox();
      </script>
      
      

      现在,如果您在浏览器中打开页面并单击缩略图图像之一,您将看到全尺寸图像在 Colorbox 中打开。您可以通过后退和前进按钮在所有全尺寸图像之间导航,而无需关闭灯箱。您还可以通过在键盘上按左右箭头键之间移动图像。分页指示器可帮助您查看您在照片集合中的位置。您还会注意到,每个链接上包含的 title 属性被重新用作每个图像的图像标题。可以通过单击关闭按钮、单击 Colorbox 外部或按键盘上的 Esc 键来关闭 Colorbox。总的来说,这是一个非常好的开箱即用的体验。

    刚刚发生了什么?

    我们使用 Colorbox jQuery 插件将图像链接列表转换为灯箱,让站点访问者能够在不离开页面的情况下浏览全尺寸图像。我们使用链接的 title 属性为图像提供标题。我们使用插件提供的五种 Colorbox 样式之一来创建一个设计良好的灯箱。

    自定义 Colorbox 的行为

    如果您查看 Colorbox 网站的 Settings 部分,您会看到有很多选项可以自定义 Colorbox 的行为方式。让我们看看如何利用其中一些选项。对于本节,我们将继续使用上一节设置的文件。

    过渡

    首先,我们将尝试不同的可用过渡效果。默认过渡效果是elastic。如果您的全尺寸图像尺寸各不相同,您会发现 Colorbox 使用一个漂亮的调整大小动画来在它们之间进行过渡。过渡的其他选项包括fadenone。让我们看看如何修改过渡。

    行动时间 —— 使用自定义过渡

    按照以下步骤更改图片之间的默认过渡效果:

    1. 对于这个例子,我们将看一下如何使用fade过渡。打开您的scripts.js文件。我们所要做的就是将fade值传递给colorbox()方法的过渡关键字,如下所示:

      $(document).ready(function(){
      $('a[rel="ireland"]').colorbox({transition:'fade'});
      });
      
      

      请注意,我们在括号内添加了一些花括号。在这些花括号内,我们可以传递键/值对以定制 Colorbox 的不同方面。在这种情况下,关键字是transition,值是'fade'。

      如果您在浏览器中重新加载页面,点击其中一个缩略图,然后点击下一个和上一个按钮来浏览图片,您会发现 Colorbox 在每张图片之间淡出然后淡入。

    2. 如果我们决定完全取消过渡会怎样?我们只需将transition关键字的值更改为'none'即可:

      $(document).ready(function(){
      $('a[rel="ireland"]').colorbox({transition:'none'});
      });
      
      

      现在,如果您在浏览器中刷新页面,您会发现图片之间没有任何过渡效果。

    刚才发生了什么?

    我们看到了如何利用 Colorbox 插件中的一个可用设置,并修改了当我们的网站访问者浏览图片时的过渡效果。

    固定大小

    在加载到 Colorbox 中的照片尺寸差异很大的情况下,您可能会决定所有调整大小会使网站访问者分心,您想为 Colorbox 设置一个固定大小。这也很容易做到,只需再传入几个键/值对即可。浏览文档,您会发现有很多用于控制 Colorbox 宽度和高度的设置。为了保持简单,我们将使用widthheight

    行动时间 —— 设置固定大小

    按照以下步骤为 Colorbox 设置固定宽度和高度:

    1. 打开您的scripts.js文件。我们将对我们的代码进行一些更改,为 Colorbox 设置固定的widthheight

      $('a[rel="ireland"]').colorbox({
      transition: 'none',
      width: '90%',
      height: '60%'
      });
      
      

      现在,如果您在浏览器中刷新页面,您会发现 Colorbox 保持相同的大小。无论图像或浏览器窗口的大小如何,Colorbox 始终会填充浏览器窗口宽度的 90%和高度的 60%。如果图像过大,图像内部会按比例调整大小以适应可用空间。

    刚才发生了什么?

    我们将widthheight设置为百分比值。如果你有可能比您站点访问者的浏览器窗口还大的大照片,这是一个非常有用的选项。将widthheight设置为百分比值可以确保在这种情况下,Colorbox 将是站点访问者浏览器窗口宽度的 90%,高度的 60%,无论浏览器窗口的大小是多少。这样,如果浏览器窗口很小,站点访问者仍然能够看到完整的照片。

    Colorbox 还为宽度和高度提供了一些其他设置:

    innerWidth/innerHeight

    这些键为 Colorbox 内部内容提供了widthheight值,而不是为 Colorbox 本身提供。在您知道实际内容的确切宽度和高度的情况下,例如视频播放器,这可能很有帮助。

    InitialWidth/initialHeight

    Colorbox 非常灵活,可以用于各种不同的内容(我们马上就会看到)。设置intialWidthinitialHeight允许您在加载任何内容之前控制 Colorbox 的大小。如果通过 Ajax 加载内容,可能需要一些时间才能加载到 Colorbox 中。设置initialWidthinitialHeight允许您指定在等待内容加载时 Colorbox 应该有多大。

    maxWidth/maxHeight

    这些键允许您为 Colorbox 设置最大宽度和最大高度。如果内容较小,则框将在屏幕上显示为较小的尺寸。但是当您加载较大的内容时,它们不会超过您指定的maxWidthmaxHeight 值。例如,如果您想为各种大小的图像设置 Colorbox,您可以允许 Colorbox 在图像之间使用淡入淡出或弹性过渡来调整大小,但是设置maxWidthmaxHeight可以确保较大的图像不会超过站点访问者的浏览器窗口。

    创建一个幻灯片

    Colorbox 还为我们提供了一个选项,可以自动循环显示所有图片,这样站点访问者就不必不断点击下一个按钮来查看它们。

    行动时间——创建幻灯片

    我们可以将我们的灯箱图片库变成幻灯片的方法如下:

    1. 打开scripts.js。我们将向我们的设置添加另一个键/值对。要在我们的 Colorbox 中创建幻灯片,将slideshow键设置为true

      $('a[rel="ireland"]').colorbox({
      transition: 'none',
      width: '90%',
      height: '60%',
      slideshow: true
      });
      
      

      现在,如果您在浏览器中刷新页面,您会看到在您打开 Colorbox 后,它会自动循环显示图片,使用您选择的任何转换效果。提供一个链接,以便站点访问者随时可以停止幻灯片:

      行动时间——创建幻灯片

    2. Colorbox 提供了更多我们可以用来控制幻灯片演示的键。我们可以为 slideshowSpeed 提供一个值来设置每张照片显示的毫秒数。如果我们不想要幻灯片自动播放,我们可以将 slideshowAuto 设置为 false。我们可以通过为 slideshowStartslideshowStop 键传入值来更改链接中显示的启动和停止幻灯片的文本,分别如下所示:

      $('a[rel="ireland"]').colorbox({
      transition: 'none',
      width: '90%',
      height: '60%',
      slideshow: true,
      slideshowSpeed: 2000,
      slideshowAuto: false,
      slideshowStart: 'Let\'s get started!',
      slideshowStop: 'Ok, that\'s enough.'
      
      

      通过这段代码,我们设置了我们的幻灯片演示每张照片显示 2 秒(2000 毫秒),不自动启动幻灯片演示,并定制了启动和停止幻灯片的链接上的文本。

      请注意,每个键/值对之间用逗号分隔,但是在最后一个键/值对后面没有逗号。在 Internet Explorer 中,最后一个后面没有逗号只是很重要 —— 如果你在 Internet Explorer 中意外地在最后一个键/值对后面放了一个逗号,它会抛出一个错误,你的 JavaScript 将无法工作。其他浏览器会忽略该错误并继续优雅地工作。在将工作提供给公众之前,请始终在 Internet Explorer 中测试您的工作。

      让我们谈一谈出现在我想用于启动和停止幻灯片演示的链接文本中的 '。由于这些是字符串,我必须将它们用引号括起来,可以是 ' 单引号也可以是 " 双引号,并且是个人偏好选择哪个。如果我想在我的字符串中使用引号,我必须转义它们 —— 这是 JavaScript 说我必须告诉 JavaScript 那些是我的字符串的一部分而不是 JavaScript 应该注意的字符的方式。

      如果我按照这种方式编写我的字符串:

      slideshowStart: 'Let's get started!'
      
      

      这将导致错误。就 JavaScript 而言,Let's 中的 ' 是字符串的结束单引号 —— 而 JavaScript 不知道如何处理行的其余部分。

      在这种情况下,如果我的个人偏好是使用双引号来编写字符串,我就不需要做任何事情。这将是完全可以接受的:

      slideshowStart: "Let's get started!"
      
      

      由于我们在字符串周围使用双引号,JavaScript 不会意外地将其读取为我们字符串的结尾。一旦 JavaScript 看到一个开头的 " 字符,它就会自动寻找匹配的结尾 " 字符。

      现在我们已经定制了我们的幻灯片演示,在浏览器中刷新页面并点击一个图片缩略图来打开 Colorbox。唯一可见的区别是添加了让我们开始吧链接。点击它启动幻灯片演示并将链接更改为说好了,这样我们就可以停止幻灯片演示。

    刚刚发生了什么?

    我们看到了如何创建和定制幻灯片演示。我们通过向 colorbox() 方法传递一系列键/值对来获取简单的灯箱照片库并进行定制。

    炫酷的登录

    使用 lightbox 来显示图片和幻灯片已经足够好了,但是 Colorbox 比这更有能力和灵活。在本节中,我们将看看如何在 Colorbox 中显示一个登录表单。请注意,我们的登录表单没有连接到任何东西,在示例情况下实际上不会起作用。但是这个相同的技术可以应用于一个动态站点,让你的站点访客可以在 lightbox 中查看登录表单。

    执行操作-创建一个花哨的登录表单

    按照以下步骤在 lightbox 中创建一个登录表单:

    1. 我们将开始设置一个 HTML 页面和相关的文件和文件夹,就像我们在第一章中所做的那样,Designer, Meet jQuery。我们的 HTML 页面将包含一个显示登录表单的标题。通常情况下,站点允许人们从站点的任何页面登录:

      <div id="example-header">
      <h1>Ireland: The Emerald Isle</h1>
      <form action="#" id="login-form">
      <div><label for="username">Username:</label> <input type="text" id="username"/></div>
      <div><label for="password">Password:</label> <input type="text" id="password"/></div>
      <div><input type="submit" value="Log In"/></div>
      </form>
      </div>
      
      
    2. 接下来,我们将打开styles.css并添加一些 CSS,以便标题显示在左侧,表单显示在右侧:

      #example-header { border-bottom:2px solid #586E75; border-top:2px solid #586E75;overflow:hidden;zoom:1; }
      #example-header h1 { float:left;padding:0;margin:0; }
      #example-header #login-form { float:right;padding-top:15px; }
      #example-header #login-form div { display:inline; }
      #login-link { display:block;float:right;padding-top:15px; }
      #login-link:focus { outline:none; }
      
      

      如果你在浏览器中查看页面,你会看到以下内容:

      执行操作-创建一个花哨的登录表单

      对于没有启用 JavaScript 的用户来说,这是完全可以接受的-他们可以从任何页面登录到网站。但我认为这有点凌乱。所以如果网站访问者启用了 JavaScript,我们将隐藏登录表单,并在网站访问者准备登录时在 Colorbox 中显示它。

    3. 接下来,我们将准备使用 Colorbox 插件,方式与我们在上一节中所做的一样:选择一个提供的 Colorbox 样式,并将其样式表附加到文档的头部,将所有必需的图片移动到你的image目录并更新 CSS 中的图片路径,并将 Colorbox 插件附加到文档的底部,在 jQuery 和我们的scripts.js标签之间。

    4. 一旦所有这些都搞定了,我们就可以开始编写我们的 JavaScript 了。打开scripts.js并编写你的文档就绪语句:

      $(document).ready(function(){
      //Our code goes here
      });
      
      
    5. 我们要做的第一件事是隐藏登录表单。我们将使用 JavaScript 而不是 CSS 来做到这一点,因为我们希望对于没有启用 JavaScript 的网站访问者来说,登录表单是可见的。我们希望在页面加载后立即隐藏表单,所以我们将在文档的ready()方法内编写我们的隐藏代码:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      });
      
      

      你会注意到我们创建了一个名为form的变量,并用它来存储表单的 jQuery 选择器。我们将不得不在我们的代码中多次引用登录表单。我们可以每次想要选择登录表单时都写$('#login-form'),但是每次,jQuery 都要重新查找 DOM 页面来找到它。如果我们将它存储在一个变量中,我们的代码将运行得更快,更高效,因为 jQuery 不必每次引用它时都查找登录表单。

      如果你在浏览器中刷新页面,你会发现登录表单已经消失了。

    6. 但是现在我们需要一个让网站访问者能够再次显示它以便登录的方法。我们将使用 jQuery 在页面上添加一个登录链接,它将出现在表单原来的位置:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      form.before('<a href="#login-form" id="login-link">Login</a>');
      });
      
      

      已经,我们再次提到了表单 —— 在表单之前插入登录链接。我们已经在 CSS 中包含了一些样式,来样式化链接并将其显示在我们想要的位置。如果你在浏览器中刷新页面,你会看到登录表单被一个登录链接替换了:

      操作时间 —— 创建一个花哨的登录表单

    7. 但是点击登录链接没有任何反应。让我们通过添加一些 Colorbox 魔法来解决这个问题。我们将选择我们的登录链接,并调用 colorbox() 方法,如下所示:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      $('#login-form').before('<a href="#login-form" id="login-link">Login</a>');
      $('#login-link').colorbox();
      });
      
      

      刷新浏览器页面,然后尝试点击链接。嗯... 这不是我们想要的结果,对吧?我们必须告诉 Colorbox 我们想加载一些已经在页面上的内容。

    8. 我们已经在链接的 href 属性中放置了登录表单的引用,所以我们会利用这一点。我们将向 colorbox() 方法传递一些键值对,告诉 Colorbox 我们想加载一些已经在页面上的内容,并确切地指定我们想要显示的内容:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      $('#login-form').before('<a href="#login-form" id="login-link">Login</a>');
      $('#login-link').colorbox({
      inline: true,
      content: $(this).attr('href')
      });
      });
      
      

      刷新浏览器页面,你会看到 Colorbox 打开了,但是它似乎是空的。那是因为我们隐藏了我们的表单。它已经加载到了 Colorbox 中,但是被隐藏了。

    9. 我们将使用另一个键值对来告诉 Colorbox 在 Colorbox 打开时显示表单:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      $('#login-form').before('<a href="#login-form" id="login-link">Login</a>');
      $('#login-link').colorbox({
      inline: true,
      content: $(this).attr('href'),
      onOpen: function(){form.show();}
      });
      });
      
      

      onOpen 是 Colorbox 插件提供的键之一。它允许我们编写一个函数,该函数将在 Colorbox 打开时运行。在这种情况下,我将找到我的表单并显示它。现在,如果你在浏览器中刷新页面,你将能够在 ColorBox 中看到表单如下:

      操作时间 —— 创建一个花哨的登录表单

    10. 这看起来已经足够好了,我们稍后会用一点 CSS 来修饰一下,让它看起来更好一些。但是当你关闭 Colorbox 时会发生什么?那个讨厌的登录表单又出现在头部了。所以我们会向我们的 colorbox() 方法传递另一个键值对,在 Colorbox 关闭时隐藏表单:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      $('#login-form').before('<a href="#login-form" id="login-link">Login</a>');
      $('#login-link').colorbox({
      inline: true,
      content: $(this).attr('href'),
      onOpen: function(){form.show();},
      onCleanup: function(){form.hide();},
      });
      });
      
      

      这将确保我们的表单在 Colorbox 关闭时被隐藏,这样它就不会再次出现在头部。

    11. 现在,让我们让我们的登录表单看起来更友好一些。打开 styles.css 文件,然后添加一些 CSS,样式化光箱内的登录表单:

      #cboxContent form div { padding:5px 0; }
      #cboxContent label { display:block; }
      #cboxContent input[type='text'] { font-size:1.2em;padding:5px;width:342px;border:1px solid #ccc;box-shadow:inset 2px 2px 2px #ddd;border-radius:5px; }
      #cboxContent input[type='submit'] { font-size:1.2em;padding:10px; }
      
      
    12. 我们还希望将登录表单框变宽一点,所以我们会向 colorbox() 方法传递一个 width 键,如下所示:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      form.before('<a href="#login-form" id="login-link">Login</a>');
      $('#login-link').colorbox({
      width: '400px',
      inline: true,
      content: $(this).attr('href'),
      onOpen: function(){form.show();},
      onCleanup: function(){form.hide();},
      });
      });
      
      

      现在,如果你在浏览器中刷新页面,你会看到我们的 Colorbox 确实是 400 像素宽,我们的登录表单已经采用了我们想要的用 CSS 创建的漂亮的块状外观,但还有一个小问题。我们的表单对于 Colorbox 来说太高了:

      操作时间 —— 创建一个花哨的登录表单

      Colorbox 脚本并没有意识到我们的表单在显示在 Colorbox 内部时具有不同的 CSS —— 它仍然期望表单的高度与在标题中显示时的高度相同。但是,该表单要小得多。如果你把鼠标放在登录表单上并向下滚动,你会看到剩下的登录表单在那里 —— 我们只是看不到它。

    13. 我们不希望在我们的 Colorbox 中出现任何滚动,所以我们将关闭它,并通过向 colorbox() 方法传递一些额外的键/值对告诉 Colorbox 调整大小以适应其内容:

      $(document).ready(function(){
      var form = $('#login-form');
      form.hide()
      form.before('<a href="#login-form" id="login-link">Login</a>');
      $('#login-link').colorbox({
      width: '400px',
      inline: true,
      scrolling: false,
      content: $(this).attr('href'),
      onOpen: function(){form.show();},
      onComplete: function(){$.colorbox.resize();},
      onCleanup: function(){form.hide();},
      });
      });
      
      

      滚动键允许我们关闭 Colorbox 内部的任何滚动,并且 onComplete 键是一个回调函数,在内容加载到 Colorbox 中后立即调用。一旦内容加载到 Colorbox 中,我们将调用一个 Colorbox 插件提供给我们的方法来调整 Colorbox 的大小以容纳其内容。

      现在,如果你在浏览器中刷新页面,你会看到 Colorbox 滑动打开以适应我们表单的新 CSS 而变得更高。完美!

      操作时间 — 创建漂亮的登录表单

    刚刚发生了什么?

    我们学会了如何将简单的标题登录表单更改为在单击时在 Colorbox 中打开登录表单的登录链接。我们通过将回调函数传递给 Colorbox 插件文档中指定的键的值来解决了此方法可能引起的任何潜在问题。我们学会了在 Colorbox 打开时调用函数、当内容加载到 Colorbox 中时以及当 Colorbox 关闭时运行函数。我们学会了通过调用 $.colorbox.resize() 方法强制 Colorbox 调整大小以适应其当前内容。

    视频播放器

    Colorbox 是足够灵活的,可以用来显示视频播放器作为内容。我们将链接到一个 YouTube 视频,然后添加一些 Colorbox 魔法来在 Colorbox 中显示视频。请注意,此示例使用了 Ajax,因此只有在上传文件到服务器或在您自己的计算机上创建服务器时才会起作用。

    操作时间 — 在灯箱中显示视频

    按照以下步骤设置 Colorbox 以播放一组视频:

    1. 我们将像通常一样开始,通过设置一个基本的 HTML 文件和关联的文件和文件夹,就像我们在第一章中所做的那样,设计师,见 jQuery。在我们 HTML 文档的主体中,我们将包含一个指向 YouTube 视频的链接:

      <p><a href="http://www.youtube.com/embed/2_HXUhShhmY?autoplay=1" id="video-link">Watch the video</a></p>
      
      

      注意关于我的视频链接的一些事情。首先,我使用的是视频的嵌入式 URL,而不是指向 YouTube 视频页面的链接。对于未启用 JavaScript 的用户,这将把他们带到 YouTube 网站上的独立视频播放器页面。对于启用了 JavaScript 的用户,这将确保只有视频播放器加载到 Colorbox 中,而不是完整的 YouTube 视频页面。其次,我向视频的 URL 添加了一个参数,将autoplay设置为 1。这是在访问者查看页面时如何使嵌入式 YouTube 视频自动播放的方法。通常情况下,自动播放视频是一个不好的主意,但在这种情况下,用户已经点击了一个标有 观看视频 的链接,所以他们很可能在点击链接后期待视频播放。

    2. 接下来,就像迄今为止的其他 Colorbox 示例一样,您需要在文档的头部附加您选择的 Colorbox 皮肤 CSS 文件,确保图像可用,如果需要的话,请更新 CSS 中图像的路径,并最后在文档的底部附加 Colorbox 插件。

    3. 现在,我们将打开我们的scripts.js文件,并准备好编写我们的自定义 JavaScript。我们将从文档就绪语句开始:

      $(document).ready(function(){
      });
      
      
    4. 接下来,我们将选择视频链接并调用colorbox()方法:

      $(document).ready(function(){
      $('#video-link').colorbox();
      });
      
      

      但是,如果我们在浏览器中刷新页面并尝试查看视频,我们会收到一个错误。那是因为我们试图通过 Ajax 加载视频,由于浏览器的安全限制,我们不能对不同服务器进行异步请求。在这种情况下,我们试图调用 youtube.com,但这不是我们 Colorbox 页面托管的地方,所以浏览器阻止了我们的请求。

    5. 幸运的是,我们可以创建一个iframe并将我们的外部内容加载到iframe中。而且幸运的是,Colorbox 提供了一种让我们轻松实现这一点的方法。我们只需向colorbox()方法传递一个键/值对,将iframe设置为true,就像下面这样:

      $('#video-link').colorbox({
      iframe: true
      });
      
      

      现在我们的视频加载到了 Colorbox 中,但是 Colorbox 不知道我们的视频有多大,所以我们看不到它。

    6. 我们必须告诉 Colorbox 我们期望视频播放器有多大。我们将通过为innerWidthinnerHeight传递键/值对来实现这一点。在这种情况下,我们使用innerWidthinnerHeight而不是宽度和高度,因为我们传递的是我们想要视频播放器(或内容)的大小,而不是我们想要 Colorbox 的大小:

      $('#video-link').colorbox({
      iframe: true,
      innerWidth: '640px',
      innerHeight: '480px'
      });
      
      
    7. 我们还可以使用 Colorbox 创建一种让用户轻松查看多个视频的方式。让我们回到index.html,而不是只添加一个视频链接,我们将在页面上添加一个收藏视频的列表。我们为每个视频设置一个rel属性为favorites,并提供一个title属性,这样我们的视频就会在下面显示标题:

      <h3>Favorite Videos</h3>
      <ul>
      <li><a href="http://www.youtube.com/embed/itn8TwFCO4M?autoplay=1" rel="favorites" title="Louis CK and Everything is Amazing">Everything is Amazing</a></li>
      <li><a href="http://www.youtube.com/embed/UN0A6h9Wc5c?autoplay=1" rel="favorites" title="All This Beauty by The Weepies">All This Beauty</a></li>
      <li><a href="http://www.youtube.com/embed/ZWtZA-ZmOAM?autoplay=1" rel="favorites" title="ABC's That's Incredible">That's Incredible</a></li>
      </ul>
      
      
    8. 我们在scripts.js中唯一需要更新的是更新选择器。我们不再通过 ID 选择单个链接,而是通过它们的rel属性选择我们的一组收藏链接:

      $('a[rel="favorites"]').colorbox({
      iframe:true,
      innerWidth:'640px',
      innerHeight: '480px'
      })
      
      

      如果您在浏览器中查看页面,您会发现在视频下有一个标题,并且有下一个和上一个按钮,允许您在不关闭 Colorbox 的情况下在视频之间导航。

    9. 唯一有点尴尬的是,当我们显示视频而不是图像时,我们的分页指示器显示“图像 1/3”。幸运的是,Colorbox 提供了一种让我们使用current键自定义此文本的方法:

      $('a[rel="favorites"]').colorbox({
      iframe:true,
      innerWidth:'640px',
      innerHeight: '480px',
      current: 'Video {current} of {total}'
      })
      
      

      现在,我们的分页指示器正确显示为 Video 1 of 3。我们的网站访客可以轻松地从一个视频转移到另一个视频,而不必关闭 Colorbox,每个视频都显示标题:

      行动时间——在灯箱中显示视频

    刚刚发生了什么?

    我们学会了如何在 Colorbox 中创建独立的视频播放器和多个视频播放器。我们学会了传递键/值对以告诉 Colorbox 在iframe中加载外部内容,以解决跨域 Ajax 限制。我们还学会了如何修改分页指示器文本以适应我们当前的内容类型。我们使用了innerWidthinnerHeight键来设置视频播放器的大小。

    单页网页画廊

    接下来,我们将看看如何创建一个单页网页画廊,展示你喜欢的网站或你自己设计的所有令人难以置信的网站。请注意,此示例使用了 Ajax,因此您必须将您的页面上传到网络服务器,或者在您自己的计算机上创建一个网络服务器才能看到其运行情况。

    行动时间——创建一个单页网页画廊

    按照以下步骤创建一个单页网页画廊:

    1. 我们将从设置一个基本的 HTML 文件和相关文件和文件夹开始,就像我们在第一章中所做的那样,设计师,遇见 jQuery。在我们的 HTML 文档的主体中,我们将创建一个链接列表,链接到我们想在我们的设计画廊中包含的网站:

      <h3>One-Page Web Design Gallery</h3>
      <ul>
      <li><a href="http://packtpub.com" rel="gallery">Packt Publishing</a></li>
      <li><a href="http://nataliemac.com" rel="gallery">NatalieMac</a></li>
      <li><a href="http://google.com" rel="gallery">Google</a></li>
      </ul>
      
      

      请注意,我为每个链接都添加了等于galleryrel属性。

    2. 现在,就像其他 Colorbox 示例一样,选择一个样式并将样式表附加到文档的头部,在页面中使所有必要的图像可用,如果需要更新 CSS 中图像的路径,并在页面底部附加 Colorbox 插件。

    3. 接下来,我们将打开我们的scripts.js文件并添加我们的文档就绪语句:

      $(document).ready(function(){
      });
      
      
    4. 接下来,我们将选择所有rel属性等于gallery的链接,并调用colorbox()方法:

      $(document).ready(function(){
      $('a[rel="gallery"]').colorbox();
      });
      
      
    5. 就像我们在视频示例中所做的一样,我们将iframe键设置为true,因为我们正在从其他域加载内容。我还将 ColorBox 的widthheight设置为90%,这样它几乎占据了整个浏览器窗口。我还将调整分页指示器文本,将其更改为Web Site,而不是Image:

      $('a[rel="gallery"]').colorbox({
      iframe: true,
      width: '90%',
      height: '90%',
      current: 'Web Site {current} of {total}'
      });
      
      

      现在,如果您在浏览器中刷新页面,您会发现单击其中一个链接会打开一个 Colorbox 并将该网站加载到 Colorbox 中。网站访客可以与加载的网站进行交互,就像他们将其加载到单独的浏览器窗口中一样,浏览页面等。完成一个站点后,他们可以单击下一个箭头访问列表中的下一个网站,然后在完成时单击键盘上的 Esc 键或单击关闭按钮或单击 Colorbox 外部的任何地方关闭 Colorbox。

    注意

    请注意,网站所有者有可能阻止您将其网站加载到 iframe 中的能力。如果您使用 MAMP 或 WAMP 设置了本地服务器,那么您可能会注意到 Google 示例无法加载到您的页面中。但是,如果您将代码上传到外部服务器,则可以加载。务必测试您要在网站图库中使用的所有站点,以确保它们按预期工作。

    刚刚发生了什么?

    我们利用创建 Colorbox 视频播放器所学到的大部分内容来在 Colorbox 中显示外部网站。这允许我们的网站访客在不离开我们的页面的情况下浏览一系列网站。我们再次告诉 Colorbox 将我们的内容加载到 iframe 中,以解决跨域 Ajax 限制。我们自定义了分页指示器文本,并为 Colorbox 设置了宽度和高度。

    总结

    我们已经看过了适应性和灵活性的颜色框插件的几种用法,它可以用来在灯箱中显示任何类型的内容。它可用于创建可浏览的图像库,提供对表单和视频播放器的访问,而不会在页面上堆积笨重的 UI 元素,甚至可以创建可浏览的网站图库。颜色框插件完全由 CSS 样式化,使得灯箱可以呈现您想象出的任何外观。该插件甚至包括可用作创建自己的灯箱设计起点的矢量图像资源。通过向 colorbox() 方法传递一系列键值对,可以修改灯箱的行为,使得 Colorbox 插件适用于任何可能的灯箱用途。

    接下来,我们将看一下另一个常见的网站任务:创建幻灯片演示。

    第九章:创建幻灯片

    幻灯片通常是在 Flash 中创建的,是展示照片、产品、插图、作品集等的绝佳方式。创建幻灯片是 jQuery 开发人员最常见的任务之一。在本章中,我们将看看如何从头开始创建一个简单的幻灯片,然后探讨三个创建华丽、动态且功能齐全的幻灯片的强大插件。

    在本章中,我们将涵盖以下内容:

    • 如何规划幻灯片

    • 如何从头开始编写一个简单的淡入淡出幻灯片

    • 如何使用 CrossSlide 插件创建平移和缩放幻灯片

    • 如何使用 Nivo Slider 插件创建具有有趣过渡效果的幻灯片

    • 如何使用 Galleriffic 插件创建缩略图幻灯片

    规划幻灯片

    在准备构建 jQuery 幻灯片时,有几个要考虑的事项。它们如下:

    • 首先,您必须决定对于禁用 JavaScript 的用户来说,体验会是什么样的。幻灯片中各个内容片段的优先级应该成为您的指南。如果幻灯片只是展示网站其他地方可用的内容片段,那么只需展示一张照片或幻灯片就足够了。如果幻灯片是访问内容的唯一方式,那么您必须确保将内容提供给未启用 JavaScript 的用户。在本章的各个示例中,我们将看看这两种策略。

    • 其次,您必须确定幻灯片中的所有项目是否大小相同还是大小不同。出于显而易见的原因,处理所有大小和宽高比相同的项目是最容易的,但有时对所有项目设置相同大小是不切实际或不可能的。随着我们的讨论,我将介绍哪些幻灯片适合相同大小的内容,哪些适合不同大小的内容。

    • 接下来,您需要考虑您的网站访问者是否需要对幻灯片有任何控制。有时,只需让您的图像自动轮换很方便。其他时候,允许网站访问者暂停幻灯片,或手动向前和向后移动幻灯片会很有帮助。我会告诉您每种幻灯片方法为您的网站访问者提供了多少控制。

    简单淡入淡出幻灯片

    在本节中,您将学习如何构建一个简单的淡入淡出幻灯片。这种类型的幻灯片非常适合相同大小的图像,并且在禁用 JavaScript 时可以显示为单个图像。最后,这种类型的幻灯片不向您的网站访问者提供任何对幻灯片的控制。他们无法暂停幻灯片或手动浏览幻灯片。

    行动时间 —— 创建一个简单的淡入淡出幻灯片

    按照以下步骤创建一个简单的淡入淡出幻灯片:

    1. 我们将开始创建一个基本的 HTML 文档以及与之关联的文件和文件夹,就像我们在第一章设计师,见 jQuery中所做的那样。在 HTML 文档的正文中,包括一系列图片。每个列表项将包含一张图片,可选择包装在链接中。以下是我的图片列表的示例:

      <ul id="crossfade">
      <li>
      <a href="http://en.wikipedia.org/wiki/Agua_Azul"><img src="img/AguaAzul.jpg" alt="Agua Azul"/></a>
      </li>
      <li>
      <a href="http://en.wikipedia.org/wiki/Burney_Falls"><img src="img/BurneyFalls.jpg" alt="Burney Falls"/></a>
      </li>
      <li>
      <a href="http://en.wikipedia.org/wiki/Venezuala"><img src="img/Cachoeira_do_Pacheco.jpg" alt="Cachoeira do Pacheco"/></a>
      </li>
      </ul>
      
      
    2. 接下来,我们将编写几行 CSS 来为幻灯片添加样式。幻灯片一次只显示一张图片,显示一张图片的最简单方法是将图片堆叠在一起。如果网站访问者禁用了 JavaScript,他们将只看到列表中的最后一张幻灯片:

      #crossfade { position:relative;margin:0;padding:0;list-style-type:none;width:600px;height:400px;overflow:hidden; }
      #crossfade li { position:absolute;width:600px;height:400px; }
      
      

      如果您在浏览器中查看页面,您将看到幻灯片中的最后一项可见,但其他项都不可见—它们都叠放在最后一项下面。这就是禁用 JavaScript 的网站访问者的体验。

    3. 接下来,打开 scripts.js,我们将开始编写我们的 JavaScript 代码。这个脚本将与我们以前设置的脚本有些不同。我们不再是在文档加载或网站访问者点击链接时发生一次性事件,而是实际上要设置一个在定时间隔上发生的函数。例如,如果我们希望幻灯片的每一张幻灯片可见三秒钟,我们将必须设置一个每三秒钟调用一次的切换幻灯片的函数。

      我们已经在页面上将幻灯片叠放在一起,并且最后一项在顶部。想想你如何处理一叠照片。您查看顶部的照片,然后将其移至堆栈底部以查看第二张照片。然后,您将第二张照片移至底部以查看第三张照片,依此类推。我们将同样的原理应用于我们的幻灯片。

      scripts.js 中,创建一个名为 slideshow 的函数。这是我们在想要切换照片时每三秒调用的函数。

      function slideshow() {
      }
      
      
    4. 在我们的函数内部,我们需要做的第一件事是选择堆栈中的第一张照片。

      function slideshow() {
      $('#crossfade li:first')
      }
      
      
    5. 现在我们已经有了堆叠中的第一张照片,我们只需要将它移到堆栈底部以使下一张照片可见。我们可以使用 jQuery 的 appendTo() 方法来实现。这将从列表开头删除第一张照片,并将其追加到列表末尾。

      function slideshow() {
      $('#crossfade li:first').appendTo('#crossfade');
      }
      
      
    6. 我们的翻转照片的函数已经准备好了。现在我们只需要在页面加载时进行一些初始设置。然后,我们将每三秒设置一次调用我们的翻转照片的函数。我们将在文档上调用 ready() 方法。

      $(document).ready(function(){
      // Document setup code will go here
      });
      function slideshow() {
      $('#crossfade li:first').appendTo('#crossfade');
      }
      
      
    7. 一旦我们的文档准备就绪,我们就要准备我们的幻灯片。我们将从选择幻灯片中的所有照片开始。

      $(document).ready(function(){
      $('#crossfade li')
      });
      
      
    8. 接下来,我们要隐藏幻灯片中的所有照片。

      $(document).ready(function(){
      $('#crossfade li').hide();
      });
      
      
    9. 然后,我们将过滤照片列表,只获取第一张。

      $(document).ready(function(){
      $('#crossfade li').hide().filter(':first');
      });
      
      
    10. 最后,我们将使第一张照片可见。所有其他照片将保持隐藏。

      $(document).ready(function(){
      $('#crossfade li').hide().filter(':first').show();
      });
      
      
    11. 刷新浏览器页面后,你会发现,如果没有启用 JavaScript,最后一个可见的幻灯片现在被隐藏了,而列表中的第一个幻灯片现在可见了。现在,剩下的事情就是每三秒调用我们的翻页函数。为此,我们将使用一个名为setInterval()的 JavaScript 方法。这允许我们以固定的时间间隔调用一个函数。我们向setInterval传递两个值:要调用的函数的名称以及应该在函数调用之间经过的毫秒数。例如,要每三秒(或 3000 毫秒)调用我的幻灯片函数,我会这样写:

      $(document).ready(function(){
      $('#crossfade li').hide().filter(':first').show();
      setInterval(slideshow, 3000);
      });
      
      
    12. 现在,我们每隔三秒调用一次我们的翻页函数,所以你期望如果你在浏览器中刷新页面,你会看到照片每三秒变化一次,但事实并非如此。回顾代码,很容易看出出了什么问题——尽管照片堆栈的实际顺序每三秒都在改变,但除了第一张照片之外,所有的照片都是不可见的。无论第一张照片是否在顶部,它都是唯一可见的照片,因此我们的幻灯片似乎没有变化。我们将不得不回到我们的slideshow函数,并修改它使当前照片不可见,并使堆栈中的下一张照片可见。由于我们希望照片以一个漂亮、缓慢的交叉淡入淡出效果切换,我们将调用fadeOut()方法将第一张照片淡出为透明,并且我们将向该方法传递slow以确保它花费足够的时间:

      function slideshow() {
      $('#crossfade li:first').fadeOut('slow').appendTo('#crossfade');
      }
      
      
    13. 现在,我们需要移动到列表中当前不可见的下一张照片,并使其不透明。我们将使用next()方法获取列表中的下一项,然后调用fadeIn()方法使其出现。再次,由于我们想要一个缓慢的效果,我们将slow传递给fadeIn()方法:

      function slideshow() {
      $('#crossfade li:first').fadeOut('slow').next().fadeIn('slow').appendTo('#crossfade');
      }
      
      
    14. 最后,我们的 jQuery 方法链有点麻烦。我们从堆栈中的第一张照片开始,淡出它,然后移到堆栈中的第二张照片,并淡入。然而,当我们调用appendTo()方法时,我们将第二张照片添加到末尾——我们将第二张照片移动到底部而不是第一张照片。幸运的是,jQuery 为我们提供了一个方法来返回到我们的原始选择——end()方法。我们可以在淡入第二张照片后调用end()方法,以确保将第一张照片附加到照片堆栈的底部:

      function slideshow() {
      $('#crossfade li:first').fadeOut('slow').next().fadeIn('slow').end().appendTo('#crossfade');
      }
      
      

    刚才发生了什么?

    如果你在浏览器中刷新页面,你会看到一个漂亮的交叉淡入淡出的幻灯片。当一张照片淡出时,下一张照片就会淡入,平滑地在每张照片之间过渡。由于我们不断地将堆栈中的顶部照片移到底部,我们永远不会到达幻灯片的结尾,就像你可以不断地翻阅一叠照片一样。

    我们设置了一个幻灯片功能,选择了堆栈中的第一张照片,淡出它,并将它移动到堆栈的底部。同时,我们正在找到堆栈中的第二张照片并将其淡入。我们使用了 jQuery 链接的强大功能,只需一行代码就可以完成所有操作。

    我们设置了三秒的间隔,并在每个三秒的间隔结束时调用我们的照片翻转函数。

    最后,我们在文档加载后做了一些设置工作 —— 隐藏所有照片,然后使第一张照片可见。这将确保照片始终按顺序显示在我们的幻灯片中。

    接下来,让我们看看另一个具有一些花哨过渡效果的插件。

    Nivo Slider

    在本节中,我们将看看如何充分利用来自 Dev 7 Studios 的 Nivo Slider 插件。Nivo Slider 提供了一些引人注目的照片之间的过渡效果,并提供了许多配置选项。Nivo Slider 非常适合尺寸完全相同的照片,并且很容易在 JavaScript 禁用的情况下显示单张照片以代替幻灯片。站点访问者可以手动向前和向后浏览幻灯片,并且当鼠标移动到幻灯片上时,幻灯片会暂停。

    Nivo Slider 与本书中大多数我们将介绍的插件有些不同。该插件本身是根据 MIT 许可证开源的(nivo.dev7studios.com/license/),可以免费下载和使用。此外,还有付费版本的插件供 WordPress 用户使用,包括支持、自动更新和在高级 WordPress 主题中包含插件的权限。我们在本节中创建的幻灯片使用的是该插件的免费开源版本。

    采取行动的时间 —— 创建 Nivo Slider 幻灯片

    按照以下步骤创建具有花哨过渡效果的图像幻灯片:

    1. 我们将通过设置一个基本的 HTML 文件和相关文件和文件夹来开始,就像我们在第一章 设计师,遇见 jQuery 中所做的那样。在 HTML 文档的正文中,Nivo Slider 只需要一个容器<div>内的一组图像。

      如果我们希望幻灯片的每个幻灯片链接到另一个页面或网络位置,我们可以选择将每个图像包装在链接中,但这并不是必需的。Nivo 也可以正常使用未链接的图像。<img> 标签的 title 属性用于显示幻灯片的标题。

      <div id="slideshow">
      <a href="http://en.wikipedia.org/wiki/Agua_Azul"><img src="img/AguaAzul.jpg" alt="Agua Azul" title="Agua Azul, Mexico"/></a>
      <a href="http://en.wikipedia.org/wiki/Burney_Falls"><img src="img/BurneyFalls.jpg" alt="Burney Falls" title="Burney Falls, California, USA"/></a>
      <a href="http://en.wikipedia.org/wiki/Venezuala"><img src="img/Cachoeira_do_Pacheco.jpg" alt="Cachoeira do Pacheco" title="Cachoeira do Pacheco, Venezuela"/></a>
      <a href="http://en.wikipedia.org/wiki/Deer_Leap_Falls"><img src="img/Deer_Leap_Falls.jpg" alt="Deer Leap Falls" title="Deer Leap Falls, Pennsylvania, USA"/></a>
      <a href="http://en.wikipedia.org/wiki/Fulmer_Falls"><img src="img/Fulmer_Falls.jpg" alt="Fulmer Falls" title="Fulmer Falls, Pennsylvania, USA"/></a>
      <a href="http://en.wikipedia.org/wiki/Hopetoun_Falls"><img src="img/Hopetoun_Falls.jpg" alt="Hopetoun Falls" title="Hopetoun Falls, Victoria, Australia"/></a>
      <a href="http://en.wikipedia.org/wiki/Ohiopyle_State_Park"><img src="img/Jonathans_Run.jpg" alt="Jonathan's Run" title="Jonathan's Run, Pennsylvania, USA"/></a>
      <a href="http://en.wikipedia.org/wiki/Kjosfossen"><img src="img/Kjosfossen.jpg" alt="Kjosfossen" title="Kjosfossen, Norway"/></a>
      <a href="http://en.wikipedia.org/wiki/Krimml_Waterfalls"><img src="img/KrimmlFalls.jpg" alt="Krimml Falls" title="Krimml Falls, Salzburgerland, Austria"/></a>
      <a href="http://en.wikipedia.org/wiki/Madhabkunda"><img src="img/Madhabkunda_Falls.jpg" alt="Madhabkunda Falls" title="Madhabkunda Falls, Bangladesh"/></a>
      <a href="http://en.wikipedia.org/wiki/Manavgat_Waterfall"><img src="img/Manavgat.jpg" alt="Manavgat Waterfall" title="Manavgat Waterfall, Turkey"/></a>
      <a href="http://en.wikipedia.org/wiki/Niagra_Falls"><img src="img/Niagara_Falls.jpg" alt="Niagara Falls" title="Niagara Falls, USA and Canada"/></a>
      <a href="http://en.wikipedia.org/wiki/British_Columbia"><img src="img/Nymph_Falls.jpg" alt="Nymph Falls" title="Nymph Falls, British Columbia, Canada"/></a>
      </div>
      
      
    2. 接下来,我们将添加一些 CSS,将图像堆叠在一起,并为我们的幻灯片设置固定的宽度和高度:

      #slideshow { position:relative;width:600px;height:400px; }
      #slideshow img { position:absolute;top:0;left:0; }
      
      
    3. 现在,前往nivo.dev7studios.com/pricing/下载 Nivo Slider 插件。在标记为jQuery plugin的左框中,你会找到Download链接。采取行动的时间 —— 创建 Nivo Slider 幻灯片

      点击Download链接,将 zip 文件保存到您的计算机上。

    4. 解压文件夹并查看其内容。执行操作的时间 — 创建 Nivo Slider 幻灯片播放

      有一个包含示例 HTML 文件以及图像、脚本和样式的演示文件夹。插件有两个版本 —— 源版本和打包压缩版本。还有一个许可证的副本,比你期望的要短和简单,所以请随意查看。有一个 CSS 文件,然后有一个包含三个其他文件夹的主题文件夹:default, ormanpascal。这是插件附带的三个示例主题。你可以选择其中一个示例主题,创建你自己的主题,或者修改其中一个示例主题以适应你的口味。

    5. 让我们将必要的文件复制并准备好使用。首先,将nivo-slider.css复制到你自己的styles文件夹中。选择一个主题并将整个文件夹复制到你自己的styles文件夹中。然后将jquery.nivo.slider.pack.js复制到你自己的scripts文件夹中,与 jQuery 放在一起。你的设置应该像下面的图片一样:执行操作的时间 — 创建 Nivo Slider 幻灯片播放

    6. 接下来,我们将设置我们的 HTML 文件以使用 Nivo Slider。在文档的<head>部分,包含选定主题的nivo-slider.css文件以及你的styles.css文件之前:

      <head>
      <title>Chapter 9: Creating Slideshows</title>
      <link rel="stylesheet" href="styles/nivo-slider.css"/>
      <link rel="stylesheet" href="styles/default/default.css"/>
      <link rel="stylehseet" href="styles/styles.css"/>
      </head>
      
      
    7. 在 HTML 文档底部,紧挨着闭合的</body>标签下方,插入<script>标签以引入 Nivo Slider 插件,位置在 jQuery 和你的scripts.js文件之间:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.nivo.slider.pack.js"></script>
      <script src="img/scripts.js"></script>
      </body>
      
      
    8. 打开scripts.js并在文档上调用ready()方法,这样我们的幻灯片将在页面在浏览器窗口加载时立即开始:

      $(document).ready(function(){
      //Nivo Slider code will go here
      });
      
      
    9. 接下来,我们将选择幻灯片放置的容器元素:

      $(document).ready(function(){
      $('#slideshow');
      });
      
      
    10. 最后,我们将调用nivoSlider()方法:

      $(document).ready(function(){
      $('#slideshow').nivoSlider();
      });
      
      

      现在,如果你在浏览器中查看页面,你会看到我们的幻灯片已经创建了。过渡效果的默认设置是对每个过渡使用不同的随机效果,所以如果你观看一段时间,你会对 Nivo Slider 包含的不同类型的过渡效果有一个很好的了解。

      你还会注意到我们作为每个图像的title属性包含的值被显示为每个图像的标题。

    11. 现在让我们利用 Nivo Slider 插件提供的一些自定义选项。我们选项的文档可以在nivo.dev7studios.com/support/jquery-plugin-usage/找到。

      在文档页面底部,你会找到可用过渡效果的列表。我个人最喜欢的过渡效果叫做 boxRain。让我们设置它成为唯一使用的过渡效果。我们将通过在一对花括号内传递一组键/值对给nivoSlider()方法来自定义 Nivo Slider 插件:

      $(document).ready(function(){
      $('#slideshow').nivoSlider({
      effect: 'boxRain'
      });
      });
      
      
    12. 我们可以指定盒子动画应包含的行数和列数。 默认情况下,有八列和四行,但让我们增加一下,以便 boxRain 过渡使用更多(更小的)盒子:

      $(document).ready(function(){
      $('#slideshow').nivoSlider({
      effect: 'boxRain',
      boxCols: 10,
      boxRows: 5
      });
      });
      
      
    13. 我们还可以自定义动画速度和每张幻灯片显示的时间:

      $(document).ready(function(){
      $('#slideshow').nivoSlider({
      effect: 'boxRain',
      boxCols: 10,
      boxRows: 5,
      animSpeed: 800,
      pauseTime: 4000
      });
      });
      
      

      我将 animSpeed 设置为 800 毫秒,以便 boxRain 过渡效果需要 800 毫秒才能完成。 我还将 pauseTime 设置为 4000,因此幻灯片中的每个图像都可见 4000 毫秒或四秒。

    刚才发生了什么事?

    我们设置了 Nivo Slider 插件,展示了具有令人印象深刻的过渡效果的幻灯片。 我们学会了如何适当设置 HTML 文档,如何调用 nivoSlider() 方法以及如何自定义一些幻灯片设置。

    尝试一下吧——自定义幻灯片

    除了我们使用的自定义选项之外,幻灯片还提供了几种其他配置选项,包括显示或隐藏上/下一页按钮的能力,设置分页显示或是否显示以及用于编写幻灯片的自定义功能的大量回调函数。 除此之外,您还可以完全自定义用于创建幻灯片的 CSS 和图像,使其看起来任何你想要的样子。

    尝试着自定义一个幻灯片,以匹配任何你想要的设计,并尝试使用 Nivo Slider 提供的其他自定义选项。 创建自己设计的自定义幻灯片。

    接下来,我们将看看如何创建缩略图照片画廊。

    Galleriffic 幻灯片

    Trent Foley 的 Galleriffic 幻灯片允许您将完整尺寸照片的链接列表转换为照片幻灯片。 这种方法与我们迄今为止看到的其他画廊有些不同,那里的重点是将完整尺寸的照片插入文档,然后将它们动画成幻灯片。 相反,Galleriffic 将一个完整尺寸照片的链接列表转换为幻灯片。 这些链接作为浏览幻灯片的一种方式保留在页面上。

    Galleriffic 幻灯片可以与大小和纵横比略有不同的照片集合一起使用,但如果不同照片之间的差异太大,那么设置 CSS 来优雅地处理幻灯片将是一个挑战。 Galleriffic 幻灯片使您的站点访问者可以手动导航到幻灯片中的任何照片,并为幻灯片提供了下一张、上一张和播放/暂停按钮。 对于禁用 JavaScript 的站点访问者,将提供一系列链接,这些链接将链接到照片的全尺寸版本。

    我们还将探讨一种简单的技术,您可以根据 JavaScript 是否启用来应用不同的 CSS 到页面上。当访问者在没有启用 JavaScript 的情况下访问您的网站时,这种技术可以应用在各种情况下,为您提供对内容呈现方式的更多控制。

    行动时间——创建一个 Galleriffic 幻灯片秀

    按照以下步骤使用 Galleriffic 插件创建幻灯片秀:

    1. 首先,我们将额外努力规划幻灯片秀将如何在启用和未启用 JavaScript 的网站访问者中出现。如果网站访问者没有 JavaScript,我们将向他们展示一个缩略图网格,并在下方显示标题。单击缩略图将向他们显示照片的全尺寸版本。

      页面将看起来像以下屏幕截图:

      行动时间——创建一个 Galleriffic 幻灯片秀

      对于使用 JavaScript 的用户,我想在主幻灯片区域旁边显示一个较小的缩略图网格,如下面的屏幕截图所示:

      行动时间——创建一个 Galleriffic 幻灯片秀

      缩略图的情况下,标题不重要,因为它们将显示在幻灯片秀下方,而不是图片下方。

    2. 在考虑我们希望页面的外观时,我们将开始设置一个 HTML 文件和相关文件和文件夹,就像我们在第一章中所做的那样,设计师,遇见 jQuery。为每张照片创建一个 100x100 的缩略图,并将它们存储在您的images文件夹内的一个thumbs文件夹中。我们将使用这些缩略图在 HTML 文档的正文中创建一个到全尺寸照片的链接列表。

      <ul class="thumbs">
      <li>
      <a class="thumb" title="Agua Azul, Mexico" href="images/600/AguaAzul.jpg"><img src="img/AguaAzul.png" alt="Agua Azul"/></a>
      <div class="caption">Agua Azul, Mexico</div>
      </li>
      <li>
      <a class="thumb" title="Burney Falls, California, USA" href="images/600/BurneyFalls.jpg"><img src="img/BurneyFalls.png" alt="Burney Falls"/></a>
      <div class="caption">Burney Falls, California, USA</div>
      </li>
      <li>
      <a class="thumb" title="Cachoeira do Pacheco, Venezuela" href="images/600/Cachoeira_do_Pacheco.jpg"><img src="img/Cachoeira_do_Pacheco.png" alt="Cachoeira do Pacheco"/></a>
      <div class="caption">Cachoeira do Pacheco, Venezuela</div>
      </li>
      <li>
      <a class="thumb" title="Deer Leap Falls, Pennsylvania, USA" href="images/600/Deer_Leap_Falls.jpg"><img src="img/Deer_Leap_Falls.png" alt="Deer Leap Falls"/></a>
      <div class="caption">Deer Leap Falls, Pennsylvania, USA</div>
      </li>
      </ul>
      
      

      注意

      我们在每个链接上都包含了一个title属性,以确保当鼠标悬停在每个缩略图上时会显示一个工具提示,其中包含此照片的简短描述。我还在每个图像标签上包含了一个alt属性,以便无法看到图像的任何原因的网站访问者仍然可以访问该图像的描述。

      在每个<li>内部,我还包括了一个<div>,带有类名为caption,其中包含将显示在缩略图下方或幻灯片秀中图片下方的标题。

      这是足够为非 JavaScript 版本的幻灯片秀设置 HTML 的,但是 Galleriffic 插件需要页面上更多的元素。

    3. 我们需要像以下这样,用一个带有idthumbs<div>来包裹我们的图片列表:

      <div id="thumbs">
      <ul class="thumbs">
      <li>
      ...
      </li>
      </ul>
      </div>
      
      
    4. 我们还需要在页面中添加一些空元素,用来容纳我们的幻灯片秀、幻灯片说明和幻灯片控件。

      <div id="thumbs">...</div>
      <div id="gallery">
      <div id="controls"></div>
      <div id="slideshow-container">
      <div id="loading"></div>
      <div id="slideshow"></div>
      </div>
      <div id="caption"></div>
      </div>
      
      

      这些元素在页面上的确切位置由您决定——您可以创建任何您喜欢的布局,并将幻灯片秀的各个部分放在您喜欢的页面上的任何位置。出于可用性考虑,当然,这些元素应该相对靠近一起。

      请注意,除了包含缩略图列表的 thumbs div外,我们添加到页面的其他元素都是空的。这些元素只会在访问者启用 JavaScript 时使用,并且它们内部的所有内容都将由 Galleriffic 插件自动生成。这将使它们在不使用时保持不可见。

    5. 现在,打开你的 HTML 文件,找到开头的<body>标签,添加一个classjsOff

      <body class="jsOff">
      
      
    6. 接下来,我们将为缩略图设置 CSS 样式。打开你的styles.css文件并添加这些样式:

      .thumbs { margin:0;padding:0;line-height:normal; }
      .thumbs li { display:inline-block;vertical-align:top; padding:0;list-style-type:none;margin:0; }
      .jsOff .thumbs li { width:100px;margin-bottom:5px;background:#fff; border:5px solid #fff;box-shadow:1px 1px 2px rgba(0,0,0,0.1) }
      .jsOff .caption { min-height:52px;font-size:12px; line-height:14px; }
      .jsOff #gallery { display:none; }
      
      

      CSS 在这里有两个部分。以.thumbs开头的选择器将应用于缩略图,无论访问者是否启用 JavaScript。以.jsOff开头的选择器将仅应用于没有启用 JavaScript 的访问者。这段 CSS 会创建带有标题的缩略图网格。

      我们还选择了幻灯片放映的父容器,并设置为对于没有 JavaScript 的访问者根本不显示。由于这是一组空的<div>,它们不应该占用页面上的任何空间,但这是为了确保这些额外的元素不会对没有 JavaScript 的访问者造成任何问题的额外保证。

      该页面的非 JavaScript 版本已经完成。

    7. 接下来,我们将为启用 JavaScript 的用户设置页面。我们将开始打开scripts.js文件并插入我们的文档就续语句:

      $(document).ready(function(){
      // This code will run as soon as the page loads
      });
      
      
    8. 接下来,我们将编写一些代码,将jsOff类从body中删除并替换为jsOn类。

      $(document).ready(function(){
      $('body').removeClass('jsOff').addClass('jsOn');
      });
      
      

      如果站点访问者启用了 JavaScript,jsOff类将从body中移除,替换为jsOn类。

    9. 现在,我们可以编写一些 CSS,应用于对于已启用 JavaScript 的站点访问者的缩略图列表。打开你的styles.css文件并添加这些样式:

      .jsOn .thumbs { width:288px; }
      .jsOn .thumbs li { width:86px; }
      .jsOn .thumbs img { border:3px solid #fff;max-width:80px;opacity:0.6; }
      .jsOn #thumbs { float:left; }
      
      

      这个 CSS 只会应用于启用 JavaScript 的访问者,因为只有在 JavaScript 可用来工作时,jsOn类才能应用于<body>

    10. 现在,我们将编写一些样式来控制幻灯片的各个部分,包括控件、标题和幻灯片区域本身:

      #gallery { float:left;width:600px;position:relative;background:#fff;padding:10px;margin-bottom:20px;line-height:18px; }
      .ss-controls { text-align:right;float:right;width:40%; }
      .nav-controls { float:left:width:40%; }
      #controls a { font-size:14px;color:#002B36;background:100% 0px no-repeat url(images/controls/sprite.png);padding-right:18px; }
      #controls a.pause { background-position: 100% -18px; }
      #controls a.prev { background-position: 0 -36px;padding-right:0;padding-left:18px;margin-right:10px; }
      #controls a.next { background-position: 100% -54px; }
      .caption { font-size:24px;padding:5px 0; }
      .thumbs li.selected img { border-color:#000;opacity:1; }
      
      

      我已经创建了一个小精灵,其中包含播放、暂停、上一个下一个的图像,我将应用到这些控件上。

    11. 现在,既然我们已经准备好创建一个令人惊叹的幻灯片放映,我们只需要我们的插件代码。前往 www.twospy.com/galleriffic/,在那里你会找到 Galleriffic 插件的文档和下载。你需要向下滚动页面几乎到底部才能找到下载部分。行动时间 — 创建 Galleriffic 幻灯片

      您会注意到下载有两个选项——您可以获取包含一些示例的 ZIP 文件,也可以仅获取插件代码本身。由于我们已经知道我们想要的幻灯片样式,我们将仅获取插件代码。单击链接将在浏览器窗口中打开代码本身。右键单击或从浏览器菜单中选择 文件 | 另存为 将文件保存到您自己的 scripts 文件夹中。

    12. 现在我们已经获得了插件,我们想将它包含在我们的 HTML 页面中。转到您 HTML 页面的底部,并将 Galleriffic 插件插入在 jQuery 和您的 scripts.js 文件之间:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.galleriffic.js"></script>
      <script src="img/scripts.js">
      </script>
      
      
    13. 接下来,我们将打开 scripts.js 并选择包装我们的缩略图列表的容器,并在我们改变 body 类的代码行后调用 galleriffic() 方法:

      $('body').removeClass('jsOff').addClass('jsOn');
      $('#thumbs').galleriffic();
      
      
    14. 但是,如果您在浏览器中查看页面,您会发现幻灯片不起作用。这是因为 Galleriffic 插件需要一些配置才能运行。我们将在花括号内传递一组键/值对给 galleriffic() 方法,以便我们的幻灯片运行。我们基本上必须告诉插件在哪里显示我们的幻灯片、控件和标题。

      $('#thumbs').galleriffic({
      imageContainerSel: '#slideshow',
      controlsContainerSel: '#controls',
      captionContainerSel: '#caption',
      loadingContainerSel: '#loading',
      autoStart: true
      });
      
      

      具有 idslideshow<div> 是我们将显示全尺寸图像的位置。控件将显示在具有 id 为 controls 的 div 中。 <div id="caption"> 将显示标题,而我们创建的具有 idloadingdiv 将在幻灯片初始化时显示加载动画。我还将 autoStart 设置为 true,这样幻灯片就会自动播放。

      现在,如果您在浏览器中刷新页面,您将看到幻灯片正在运行。下一页上一页 按钮允许您翻转,并且 播放/暂停 按钮使您可以控制幻灯片。

    发生了什么?

    我们设置了我们的页面以显示为禁用 JavaScript 的站点访客优化的图像缩略图。然后,我们使用了一行 JavaScript 代码来更改 body 类,以便我们可以为启用 JavaScript 的站点访客应用不同的样式。我们设置了 CSS 来显示我们的幻灯片,并调用了 galleriffic() 方法来动画显示幻灯片。站点访客可以手动在照片之间前后移动,可以单击缩略图将相应的全尺寸照片加载到幻灯片区域,并可以在任何时候暂停幻灯片。

    CrossSlide 插件

    CrossSlide 插件,由 Tobia Conforto 制作,使得不仅可以淡入淡出图像,还可以动画平移和缩放图像成为可能。如果您有各种不同尺寸的图像,则此插件非常理想。为了获得最佳效果,唯一的要求是所有图像至少与幻灯片查看区域一样大。大于幻灯片查看区域的图像将被裁剪。例如,如果幻灯片宽度为 600 像素,高度为 400 像素,那么幻灯片中使用的所有图像的宽度和高度都应至少为 600 像素和 400 像素。

    当 JavaScript 被禁用时,CrossSlide 插件将显示你放入幻灯片的任何内容作为占位符。这可以是一个单独的图像,或者是一个图像加上文本,或者任何你想要的其他类型的 HTML 内容。页面加载时,插件将删除此占位符内容,并用幻灯片替换它。

    可以提供按钮,让网站访问者停止和重新启动幻灯片播放。但是,访问者不能手动切换到各个幻灯片。

    在我们深入了解之前,我想提醒一下,与我们之前见过的一些插件相比,你会发现 CrossSlide 插件的设计不太友好。一个平移和缩放幻灯片是一个复杂的任务,而该插件只能做到让这种复杂性减轻一些。话虽如此,我相信如果你花点时间并稍微耐心一些,你就能搞清楚。

    行动时间 —— 构建 CrossSlide 幻灯片

    按照以下步骤设置 CrossSlide 幻灯片:

    1. 要开始,我们将设置一个简单的 HTML 文档和关联的文件和文件夹,就像我们在第一章中所做的那样,设计师,见 jQuery。HTML 文档的主体将包含幻灯片的容器。在容器内,放置任何您希望为禁用 JavaScript 的用户显示的内容。

      <div id="slideshow">
      <img src="img/AguaAzul.jpg" alt="Agua Azul"/>
      </div>
      
      

      我将简单地为禁用 JavaScript 的用户显示幻灯片中的第一张照片。我给我的容器 <div> 加上了 idslideshow

    2. 打开 styles.css 并添加一些 CSS 来定义幻灯片的宽度和高度:

      #slideshow { width:600px;height:400px; }
      
      
    3. 接下来,前往 tobia.github.com/CrossSlide/ 获取 CrossSlide 插件的下载和文档。行动时间 —— 构建 CrossSlide 幻灯片

      你会在页面顶部附近找到下载缩小版链接。页面的其余部分展示了 CrossSlide 插件在几个示例中的应用。浏览一下这些示例。你会发现它可以做从与本章第一节中构建的简单交叉淡入淡出幻灯片类似的事情,到完全动态的平移和缩放幻灯片的所有事情。

      现在你已经看了一些你可以使用 CrossSlide 插件创建的幻灯片类型,接下来有几件事情需要记住:

      • 首先,由于某些浏览器(即,Internet Explorer)的渲染限制,对照片进行缩放可能会影响照片显示的质量。插件的作者建议将缩放因子保持在 1 或以下,以最小化此效果。

      • 第二,因为浏览器限制为呈现完整像素,所以平移和缩放动画效果可能不太流畅,特别是对于对角线动画。您可以通过减少或避免对角线动画或选择相对较高的动画速度来减少 1 像素跳跃效果,从而使它们看起来更流畅。

      • 最后,动画可能会占用一些 CPU 资源,特别是当同时使用了平移、缩放和交叉淡化动画,就像我们在这个例子中所做的那样。这并不会使大多数新电脑遇到问题,但是根据你的网站受众,你可能希望避免同时使用所有可能的动画效果。在本教程的结尾,我将向你展示如何避免幻灯片最消耗 CPU 资源的部分,如果它在你自己或你的网站访问者的电脑上造成了问题的话。

    4. 当你点击下载压缩版链接时,插件脚本本身将在浏览器窗口中打开,就像 jQuery 本身一样。只需右键单击页面或从浏览器的菜单栏选择文件 | 另存为,将文件保存到你自己的计算机上。保留文件名jquery.cross-slide.min.js,并将文件保存在你的scripts文件夹中。

    5. 接下来,我们只需要在我们的 HTML 页面底部包含 CrossSlide 插件文件,放在 jQuery 和scripts.js之间:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.cross-slide.min.js"></script>
      <script src="img/scripts.js"></script>
      </body>
      </html>
      
      
    6. 接下来,打开你的scripts.js文件,我们将通过选择我们的幻灯片容器并调用crossSlide()方法来开始使用 CrossSlide 插件:

      var slideshow = $('#slideshow');
      slideshow.crossSlide();
      
      

      请记住,变量只是某物的容器。在这种情况下,我们选择了幻灯片容器并将其放在一个名为slideshow的变量中。我们这样做是因为我们将在脚本中多次引用这个容器。通过将幻灯片容器保存在一个变量中,我们可以防止 jQuery 每次想要引用它时都需要查询 DOM,使我们的代码更加高效。

    7. 此时,如果在浏览器中加载页面,你会发现调用crossSlide()方法似乎对我们的页面没有产生任何效果。你仍然会在我们的幻灯片容器内看到占位内容,而且没有幻灯片播放。这是因为我们不仅需要向crossSlide()方法传递设置,还需要传递我们想在幻灯片中显示的照片列表。在crossSlide()方法的括号内,插入一对花括号,我们将传递一个键值对来配置图片之间淡入淡出的时间长度,单位为秒:

      var slideshow = $('#slideshow');
      slideshow.crossSlide({
      fade: 1
      });
      
      

      注意

      请注意,我们使用的时间长度单位是秒,而不是毫秒。CrossSlide 插件设置为期望秒作为时间单位,而不是我们通常在 JavaScript 中找到的毫秒。

    8. 接下来,在我们的配置设置之后,我们想要将一组照片传递给crossSlide()方法。一个数组被放在方括号中:

      slideshow.crossSlide({
      fade: 1
      }, [
      //Our list of photos will go here.
      ]
      );
      
      
    9. 每张照片都将有自己的一组描述图片 URL、标题等的键值对。每张照片都将包含在自己的一组花括号中。我们将从图片的 URL 开始,该 URL 由src键描述:

      slideshow.crossSlide({
      fade: 1
      }, [
      {
      src: 'images/1000/AguaAzul.jpg'
      }
      ]
      );
      
      
    10. 接下来,我们将另一个键值对作为照片的标题:

      slideshow.crossSlide({
      fade: 1
      }, [
      {
      src: 'images/1000/AguaAzul.jpg',
      alt: 'Agua Azul, Mexico'
      }
      ]
      );
      
      
    11. 现在,我们需要添加两个键/值对来描述平移和缩放动画的起点和终点。假设我们要从左上角平移到右下角,同时放大这张照片。这里是我们将传递给 fromto 键的值:

      slideshow.crossSlide({
      fade: 1
      }, [
      {
      src: 'images/1000/AguaAzul.jpg',
      alt: 'Agua Azul, Mexico',
      from: 'top left 1x',
      to: 'bottom right .8x'
      }
      ]
      );
      
      
    12. 最后,我们要指定动画持续的时间,以秒为单位。我将展示这张照片动画四秒钟:

      slideshow.crossSlide({
      fade: 1
      }, [
      {
      src: 'images/1000/AguaAzul.jpg',
      alt: 'Agua Azul, Mexico',
      from: 'top left 1x',
      to: 'bottom right .8x',
      time: 4
      }
      ]
      );
      
      
    13. 这是我们幻灯片的一张照片。要添加更多照片,只需在花括号内添加另一组键/值对。不要忘记用逗号将每张照片与前一张照片分隔开。请记住不要在列表中的最后一张照片后面放逗号。这是我添加了另外三张照片的示例:

      slideshow.crossSlide({
      fade: 1
      }, [
      {
      src: 'images/1000/AguaAzul.jpg',
      alt: 'Agua Azul, Mexico',
      from: 'top left 1x',
      to: 'bottom right .8x',
      time: 4
      },
      {
      src: 'images/1000/BurneyFalls.jpg',
      alt: 'Burney Falls, California, USA',
      from: 'top left 1.2x',
      to: 'bottom right .8x',
      time: 5
      },
      {
      src: 'images/1000/Cachoeira_do_Pacheco.jpg',
      alt: 'Cachoeira do Pacheco, Venezuela',
      from: '50% 0% 1.2x',
      to: '50% 60% .6x',
      time: 4
      },
      {
      src: 'images/1000/Deer_Leap_Falls.jpg',
      alt: 'Deer Leep Falls, Pennsylvania, USA',
      from: '50% 50% 1.2x',
      to: '50% 100% .8x',
      time: 3
      }
      ]
      );
      
      

      注意

      请注意,我可以选择每张照片显示的时间长度——如果我愿意,可以让一张特别惊艳的照片在页面上停留更长时间,或者更快地将较小或不太有趣的照片移出页面。

      现在,如果您在浏览器中刷新页面,您将看到您的照片的平移和缩放幻灯片放映。我们离成功越来越近了!

    14. 接下来,我们将使用我们传递给 crossSlide() 方法的标题值为每张照片创建标题。首先,我要回到我的 HTML 标记并添加一个容器用于标题。您可以使用 CSS 自定义此容器的样式:

      <div id="slideshow">
      <img src="img/AguaAzul.jpg" alt="Agua Azul"/>
      </div>
      <div class="caption"></div>
      
      

      请记住,您的标题容器必须出现在幻灯片放映容器的外部。如果您将其放在内部,当 CrossSlide 插件用幻灯片放映替换幻灯片放映容器的内容时,它将被移除。

      现在,我们有了一个显示标题的地方,所以我们只需要一种方法将我们的标题放入该容器中。crossSlide() 方法将接受一个回调方法以及我们的设置和图像数组。每次图像开始淡出到下一张图像时,都会调用此回调函数,并在淡出完成后再次调用。

      
      slideshow.crossSlide({
      fade: 1
      }, [
      {
      src: 'images/1000/AguaAzul.jpg',
      alt: 'Agua Azul, Mexico',
      from: 'top left 1x',
      to: 'bottom right .8x',
      time: 4
      },
      {
      src: 'images/1000/BurneyFalls.jpg',
      alt: 'Burney Falls, California, USA',
      from: 'top left 1.2x',
      to: 'bottom right .8x',
      time: 4
      },
      {
      src: 'images/1000/Cachoeira_do_Pacheco.jpg',
      alt: 'Cachoeira do Pacheco, Venezuela',
      from: '50% 0% 1.2x',
      to: '50% 60% .6x',
      time: 4
      },
      {
      src: 'images/1000/Deer_Leap_Falls.jpg',
      alt: 'Deer Leep Falls, Pennsylvania, USA',
      from: '50% 50% 1.2x',
      to: '50% 100% .8x',
      time: 3
      }
      ], function(index, img, indexOut, imgOut) {
      //our callback function goes here
      }
      );
      
      

      我们的回调函数传递了四个可能的值:当前图像的索引,当前图像本身,前一图像的索引和前一图像本身。图像的索引只是它在幻灯片中按编号的位置。JavaScript,像其他编程语言一样,从 0 开始计数而不是 1。因此,幻灯片中第一张图像的索引是 0,第二张图像的索引是 1,依此类推。

      记得我说过回调函数在交叉淡入淡出开始时调用一次,然后在交叉淡入淡出完成后再次调用吗?如果交叉淡入淡出正在开始,回调函数将获取所有四个值——当前图像的索引和当前图像,以及前一图像的索引和前一图像。如果交叉淡入淡出已经完成,我们将只得到两个值:当前图像的索引和当前图像本身。

    15. 我们将检查交叉淡入淡出是开始还是结束。如果交叉淡入淡出已经结束,那么我们将想要显示新照片的标题。如果交叉淡入淡出刚刚开始,那么我们将隐藏很快就会成为上一张图片的标题:

      ], function(index, img, indexOut, imgOut) {
      var caption = $('div.caption');
      if (indexOut == undefined) {
      caption.text(img.alt).fadeIn();
      } else {
      caption.fadeOut();
      }
      }
      
      

      如果交叉淡入淡出完成,那么indexOut将是undefined,因为不会有一个变量的值传递给回调函数。很容易检查该值是否未定义,以判断交叉淡入淡出动画是开始还是结束。然后,我们使用 jQuery 的text()方法将标题的文本设置为我们在每张图片中包含的alt值,并将标题渐入。另一方面,如果交叉淡入淡出动画刚开始,我们将只是将标题渐出。

      现在,如果你在浏览器中刷新页面,你会看到每张照片的标题渐隐渐现,随着交叉淡入淡出的开始。这是从一个标题平滑过渡到下一个的美好过渡。

    16. 这最后一步是可选的。如果你发现 CrossSlide 插件在我们在这个例子中设置的所有动画同时运行时,对你的计算机或你网站访问者的计算机的 CPU 负荷太大,有一个简单的配置选项可以让你跳过幻灯片最消耗 CPU 的部分 —— 即,当两张照片在平移和缩放时交叉淡入淡出。你只需将另一个键值对传递给配置选项,将variant设置为true:

      slideshow.crossSlide({
      fade: 1,
      variant: true
      }, [
      {
      src: 'images/1000/AguaAzul.jpg',
      ...
      
      

      这将改变你的幻灯片,使每张照片在开始交叉淡入淡出到下一张照片之前完成平移和缩放。

    刚刚发生了什么?

    如果你的头有点晕,不用担心 —— CrossSlide 插件绝对是我们迄今为止使用过的最专业的插件。虽然这个插件不是特别友好于设计师,但我希望你能看到,即使是这种类型的插件也在你的掌握范围内,只要你有点耐心并愿意多尝试一些。仔细研究代码示例将会让你有所收获。

    我们设置了一个容器,用于保存我们的静态内容,以供 JavaScript 禁用的用户使用。然后,我们设置了 CrossSlide 插件,将该内容替换为动态的平移和缩放幻灯片,供启用 JavaScript 的用户使用。我们将交叉淡入淡出的时间设置为 1 秒,然后传入了我们的图片数组,包括 URL、标题、动画起点、动画终点和每张图片的持续时间。最后,我们利用了 CrossSlide 插件提供的回调函数,让每张照片的标题渐入,并在照片本身开始淡出时将其渐出。我们还看了如何使幻灯片在可能引起问题的情况下更少地消耗 CPU。

    概要

    我们看了四种不同的用 jQuery 构建图片幻灯片的方法。我们从零开始建立了一个简单的交叉淡入淡出的幻灯片,没有使用插件。我们使用 Nivo Slider 插件探索了花式的过渡效果。然后我们学习了如何使用 Galleriffic 插件设置缩略图幻灯片。最后,我们看了如何使用 CrossSlide 插件构建一个平移和缩放的幻灯片。

    接下来,我们将看看如何为您网站上的各种内容构建滑块和走马灯。

    第十章:在走廊和幻灯片中显示内容

    除了幻灯片秀,我们还可以在滑块和走马灯中展示图像和文本。一次可以显示一个或多个幻灯片,并使用滑动动画在幻灯片之间进行转换。走马灯非常适合创建特色内容滑块或在较小空间内提供许多图像。我们将查看 Jan Sorgalla 的灵活和可定制的 jCarousel 插件以及如何使用它创建几种不同类型的走马灯和滑块解决方案。

    在本章中,我们将学习以下主题:

    • 使用 jCarousel 插件创建基本的水平滑块

    • 创建垂直新闻滚动条

    • 创建具有外部控件的特色内容滑块

    • 将幻灯片秀与缩略图走马灯相结合

    基本 jCarousel

    让我们首先看看如何创建基本的水平图像缩略图走马灯。jCarousel 插件包括两种不同的皮肤,因此设置基本的走马灯非常快速和简单。

    以下截图是使用该插件附带的 tango 皮肤创建的基本走马灯的示例:

    基本 jCarousel

    走廊中有十几张缩略图图像。单击其中一侧箭头将走廊左右滑动以显示下一组。

    执行操作 — 创建基本走马灯

    遵循以下步骤设置基本的图像 jCarousel:

    1. 与往常一样,我们将从我们的 HTML 开始。像在 第一章 中一样,设置一个基本的 HTML 文档和相关的文件和文件夹。在 HTML 文档的主体中,创建一个图像的无序列表。当图像具有统一大小时,走马灯效果最佳。我的图像大小为 200 像素宽,150 像素高。以下是我的 HTML 外观:

      <ul id="thumb-carousel">
      <li><img src="img/Switzerland.png" alt="Switzerland"/></li>
      <li><img src="img/CostaRica.png" alt="Costa Rica"/></li>
      <li><img src="img/Canada.png" alt="Canada"/></li>
      <li><img src="img/Seychelles.png" alt="Seychelles"/></li>
      <li><img src="img/Tuvalu.png" alt="Tuvalu"/></li>
      <li><img src="img/Iceland.png" alt="Iceland"/></li>
      <li><img src="img/SouthAfrica.png" alt="South Africa"/></li>
      <li><img src="img/Mexico.png" alt="Mexico"/></li>
      <li><img src="img/Spain.png" alt="Spain"/></li>
      <li><img src="img/Italy.png" alt="Italy"/></li>
      <li><img src="img/Australia.png" alt="Australia"/></li>
      <li><img src="img/Argentina.png" alt="Argentina"/></li>
      </ul>
      
      

      你可以看到我给无序列表分配了一个 idthumb-carousel,HTML 简单明了:只是一系列图像的列表。

    2. 接下来,我们需要下载 jCarousel 插件。该插件可以从 GitHub 下载:github.com/jsor/jcarousel执行操作 — 创建基本走马灯

      要下载插件,只需单击 ZIP 按钮。

    3. 接下来,解压文件夹并查看其内容。执行操作 — 创建基本走马灯

      在内部,我们会找到一个名为 examples 的文件夹,其中包含许多 jCarousel 插件示例。有一个包含插件文档的 index.html 文件。一个 skins 文件夹包含插件附带的两种皮肤以及这些皮肤所需的图像。最后,一个 lib 文件夹包含 jQuery,以及 jCarousel 插件的两个副本之一经过压缩的版本。

    4. 我们将使用 tango 样式和插件的压缩版本。将 jquery.jcarousel.min.js 复制到你自己的 scripts 文件夹,并将整个 tango 文件夹复制到你自己的 styles 文件夹。

    5. 接下来,我们需要将 CSS 和 JavaScript 附加到我们的 HTML 文件中。在文档的 <head> 部分,将 tango 样式的 CSS 文件附加在你自己的 styles.css 文件之前:

      <link rel="stylesheet" href="styles/tango/skin.css"/>
      <link rel="stylesheet" href="styles/styles.css"/>
      
      
    6. 在文档底部,在闭合的 </body> 标签之前,在你自己的 scripts.js 之后,附加 jCarousel 插件文件:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.jcarousel.min.js"></script>
      <script src="img/scripts.js"></script>
      
      
    7. jCarousel 滑块的 tango 样式依赖于放置在列表包装器上的 jcarousel-skin-tango 类。用 div 标签将列表包装起来,并给 div 添加适当的类:

      <div class="jcarousel-skin-tango">
      <ul id="thumb-carousel">
      ...
      </ul>
      </div>
      
      
    8. 接下来我们要做的是设置我们自己的 JavaScript。打开你的 scripts.js 文件。在文档上调用 ready 方法,选择图像列表,并调用 jcarousel() 方法:

      $(document).ready(function(){
      $('#thumb-carousel').jcarousel();
      });
      
      

      像往常一样,以这种方式调用 jcarousel() 方法将加载所有默认设置的轮播。在浏览器中刷新页面,你会看到这样的情况:

      进行操作的时间 — 创建基本的轮播

      不完全是我们想象中的样子,但是点击右侧的下一个箭头会推进轮播。让我们来看看如何设置一些自定义设置,以便按照我们预期查看完整的图像。

    9. tango 样式的 CSS 假设我们的图像宽度为 75 像素,高度也为 75 像素,但实际上我们的轮播不是这样的。我们将在我们的 styles.css 中添加几行 CSS 来调整图像的大小。首先,我们将指定单个项目的宽度和高度:

      .jcarousel-skin-tango .jcarousel-item { width:200px;height:150px;}
      
      
    10. 我们还需要调整轮播容器和剪辑容器的整体大小:

      .jcarousel-skin-tango .jcarousel-clip-horizontal { width:830px;height:150px;}
      .jcarousel-skin-tango .jcarousel-container-horizontal { width:830px; }
      
      

      你可能会想知道那个 830px 宽度是从哪里来的。每个项目宽度为 200 像素,每个图像之间有 10 个像素。

      200 + 10 + 200 + 10 + 200 + 10 + 200 = 830

      图像和它们之间的间隙的总宽度为 830 像素。

    11. 接下来,我们需要将下一个和上一个按钮往下移一点,因为我们的轮播比默认的要高,而按钮显示得太高了:

      .jcarousel-skin-tango .jcarousel-prev-horizontal,
      .jcarousel-skin-tango .jcarousel-next-horizontal { top:75px; }
      
      

      现在轮播看起来正是我们想要的样子:

      进行操作的时间 — 创建基本的轮播

    12. 最后,我们将对 jCarousel 插件本身的设置进行一些调整。像许多其他插件一样,我们可以通过在一对花括号内传递一组键/值对给 jcarousel() 方法来进行自定义。首先,让我们将 scroll 值更改为 4,这样每次按下下一个或上一个按钮时会滚动四个项目。回到你的 scripts.js 文件,并将新的键/值对添加到你的脚本中,如下所示:

      $('#thumb-carousel').jcarousel({
      scroll: 4
      });
      
      

      接下来,轮播图当前在到达开头或结尾时会硬性停止。相反,我们将使轮播图环绕 —— 如果站点访客正在查看轮播图中的最后一个项目并按下下一个按钮,则轮播图将回到开头。如果在查看第一个项目时单击后退按钮,情况也是如此。我们将为wrap键添加一个'both'值,以便轮播图将在两端环绕:

      $('#thumb-carousel').jcarousel({
      scroll: 4,
      wrap: 'both'
      });
      
      

      在浏览器中刷新页面,然后使用下一个或上一个按钮或两者的任意组合来翻页轮播图。这就是使用 jCarousel 插件创建简单轮播图的全部内容。

    刚刚发生了什么?

    我们使用 jCarousel 插件创建了一个基本的动画图像缩略图轮播图。我们使用插件中包含的一个默认外观,并通过 CSS 对我们的内容大小进行调整。一些简单的定制被传递给轮播图,以确保它按照我们想要的方式工作。

    动画新闻滚动条

    水平图像轮播图很好,但使用范围相当有限。幸运的是,jCarousel 插件足够灵活,可以用于各种不同的用途。在本节中,我们将学习如何创建一个动画新闻滚动条。

    行动时间 —— 创建动画新闻滚动条

    按照以下步骤设置垂直新闻列表:

    1. 首先,我们将像在第一章中所做的那样设置基本的 HTML 文件和相关文件和文件夹。在 HTML 文档的正文中,创建一个新闻项目的无序列表。每个新闻项目都将包含一个图片和一个包含标题和摘要的 div:

      <ul id="news-carousel">
      <li>
      <img src="img/Switzerland.png" alt="Switzerland"/>
      <div class="info">
      <h4>Switzerland</h4>
      <p>Switzerland, officially the Swiss Confederation, is a federal republic consisting of 26 cantons, with Bern as the seat of the federal authorities</p>
      </div>
      </li>
      <li>
      <img src="img/CostaRica.png" alt="Costa Rica"/>
      <div class="info">
      <h4>Costa Rica</h4>
      <p>Costa Rica, officially the Republic of Costa Rica, is a country in Central America, bordered by Nicaragua to the north, Panama to the south, the Pacific Ocean to the west and south and the Caribbean Sea to the east.</p>
      </div>
      </li>
      ...
      </ul>
      
      

      我在我的列表中总共创建了 12 个项目,每个项目都具有相同的结构。请记住,轮播图中的每个项目必须具有相同的宽度和高度。

    2. 接下来,我们将打开我们的styles.css文件,并添加一些 CSS 代码以使每个新闻项目都以我们希望的方式进行样式设置,其中图片在左侧,标题和摘要在右侧:

      #news-carousel li { overflow:hidden;zoom:1;list-style-type:none; }
      #news-carousel li img { float:left; }
      #news-carousel li .info { margin-left:210px; }
      #news-carousel h4 { margin:0;padding:0; }
      #news-carousel p { margin:0;padding:0;font-size:14px; }
      
      

      随意添加一些额外的 CSS 来样式化列表以适应您自己的口味。如果您在浏览器中打开页面,此时,您可以期望看到类似以下截图的内容:

      行动时间 —— 创建动画新闻滚动条

    3. 正如我们在简单轮播图示例中所做的那样,我们将在文档的<head>部分附加 tango 皮肤的 CSS,而在 jQuery 和我们自己的scripts.js文件之间,在文档底部附加 jCarousel 插件脚本。

    4. 接下来,打开您的scripts.js文件。我们将编写我们的文档准备语句,选择我们的新闻滚动条,并调用jcarousel()方法,就像我们在上一个示例中所做的那样。

      $(document).ready(function(){
      $('#news-carousel').jcarousel();
      });
      
      
    5. 我们将一些定制选项传递给jcarousel()方法,以调整我们的轮播图以满足我们的需求。首先,它应该是垂直的而不是水平的,所以将true作为vertical键的值传递进去:

      $('#news-carousel').jcarousel({
      vertical:true
      });
      
      
    6. 我们还希望每次滚动一个项目:

      $('#news-carousel').jcarousel({
      vertical:true,
      scroll:1
      });
      
      
    7. 还有,我们希望新闻项目列表可以无限循环,如下所示:

      $('#news-carousel').jcarousel({
      vertical:true,
      scroll:1,
      wrap:'circular'
      });
      
      
    8. 我们希望轮播图以真正的新闻滚动条方式自动播放新闻故事。我们将每三秒推进一次轮播图:

      $('#news-carousel').jcarousel({
      vertical:true,
      scroll:1,
      wrap:'circular',
      auto: 3
      });
      
      
    9. 最后但同样重要的是,我们会将动画速度减慢一点,这样在动画触发时,如果我们的网站访客正在阅读,就不会那么令人不适。600 毫秒应该足够慢了:

      $('#news-carousel').jcarousel({
      vertical:true,
      scroll:1,
      wrap:'circular',
      auto: 3,
      animation: 600
      });
      
      
    10. 现在 jCarousel 已经按我们喜欢的方式配置好了,唯一剩下的就是自定义轮播图的外观了。我们目前使用的是默认的探戈皮肤,它仍然假设我们的单个项目宽度为 75 像素,高度为 75 像素。打开你的styles.css文件,我们将从调整必要的宽度和高度开始:

      .jcarousel-skin-tango .jcarousel-item { width:475px;height:150px; }
      .jcarousel-skin-tango .jcarousel-clip-vertical { width:475px;height:470px; }
      .jcarousel-skin-tango .jcarousel-container-vertical { height:470px;width:475px; }
      
      

      我们将单个项目的大小设置为 475 像素宽,150 像素高。然后调整容器和裁剪容器的大小以显示三个项目。提醒一下——因为我们的轮播图中每个项目的高度为 150 像素,项目之间还有 10 像素的间距,我们可以如下计算容器的高度:

      150 + 10 + 150 + 10 + 150 = 470 像素

      我们在计算时使用高度而不是宽度,因为我们的轮播图现在是垂直的,而不是水平的。

    11. 接下来,我们将调整探戈风格,以适应我的网站设计。我将从用橙色换掉容器的淡蓝色方案开始,调整圆角使其变得不那么圆滑:

      .jcarousel-skin-tango .jcarousel-container { -moz-border-radius: 5px;-webkit-border-radius:5px;border-radius:5px;border-color:#CB4B16;background:#f9d4c5; }
      
      
    12. 现在,让我们将探戈皮肤的小蓝色箭头替换为横跨整个轮播图宽度的长橙色条。我已经创建了自己的箭头图形,我将在每个按钮的中间显示:

      .jcarousel-skin-tango .jcarousel-prev-vertical,
      .jcarousel-skin-tango .jcarousel-next-vertical { left:0;right:0;width:auto; }
      .jcarousel-skin-tango .jcarousel-prev-vertical { top:0;background:#cb4b16 url(images/arrows.png) 50% 0 no-repeat; }
      .jcarousel-skin-tango .jcarousel-prev-vertical:hover,
      .jcarousel-skin-tango .jcarousel-prev-vertical:focus { background-color:#e6581d;background-position:50% 0; }
      .jcarousel-skin-tango .jcarousel-next-vertical { background:#cb4b16 url(images/arrows.png) 50% -32px no-repeat;bottom:0; }
      .jcarousel-skin-tango .jcarousel-next-vertical:hover,
      .jcarousel-skin-tango .jcarousel-next-vertical:focus { background-color:#e6581d;background-position:50% -32px; }
      
      

      现在,如果你在浏览器中刷新页面,你会看到轮播图以不同的颜色方案和外观重新设计了一些:

      创建动画新闻滚动条的时间到了

      将鼠标移动到顶部或底部的条上会稍微提亮颜色,点击条将使轮播图朝着那个方向推进一个项目。

    刚刚发生了什么?

    在这种情况下,我们使用 jCarousel 插件创建了一个垂直新闻滚动条。我们的新闻滚动条每三秒自动推进一次项目。我们减慢了动画速度,以便为我们的网站访客提供更流畅的阅读体验。我们还看到了如何自定义探戈皮肤的 CSS 来适应轮播图的颜色方案和外观,以适应我们网站的设计。接下来,我们将看看如何为轮播图添加一些外部控件。

    尝试一下吧——设计您自己的轮播图

    现在你已经看到如何自定义 jCarousel 插件的外观和行为,设计你自己的轮播图吧。它可以是水平或垂直的,包含文本、图片或两者的组合。试验一下 jCarousel 插件提供给你的设置——你会在插件的文档中找到它们的列表和解释。

    特色内容滑块

    除了一次显示多个项目的轮播图之外,jCarousel 还可以用于构建一次仅显示一个项目的内容滑块。还可以构建外部控制,以为您的轮播图增加一些额外的功能。让我们看看如何创建一个具有外部分页控件的单个幻灯片特色内容滑块。

    行动时间 — 创建特色内容滑块

    我们将像往常一样,首先设置我们基本的 HTML 文件和相关的文件和文件夹,就像我们在第一章,《设计师,见识 jQuery》中所做的那样。

    1. 在 HTML 文档的主体中,我们的特色内容滑块的 HTML 标记将与我们为新闻滚动条设置的 HTML 非常相似。唯一的区别是我用更大的图片替换了图片,因为我希望图片成为滑块的主要焦点。我使用的图片尺寸为 600 像素宽,400 像素高。以下是 HTML 的示例:

      <div class="jcarousel-skin-slider">
      <ul id="featured-carousel">
      <li>
      <a href="#"><img src="img/Switzerland.jpg" alt="Switzerland"/></a>
      <div class="info">
      <h4>Switzerland</h4>
      <p>Switzerland, officially the Swiss Confederation, is a federal republic consisting of 26 cantons, with Bern as the seat of the federal authorities</p>
      </div>
      </li>
      <li>
      <a href="#"><img src="img/CostaRica.jpg" alt="Costa Rica"/></a>
      <div class="info">
      <h4>Costa Rica</h4>
      <p>Costa Rica, officially the Republic of Costa Rica, is a country in Central America, bordered by Nicaragua to the north, Panama to the south, the Pacific Ocean to the west and south and the Caribbean Sea to the east.</p>
      </div>
      </li>
      ...
      </ul>
      </div>
      
      

      我的列表总共有 12 个条目,每个条目的标记就像你在这里看到的那样。注意,我将我的列表包装在一个带有类jcarousel-skin-sliderdiv中。我们将使用这个类来使用 CSS 对我们的列表进行样式设置。

    2. 接下来,我们将为我们的项目列表设置样式。我们将在照片上叠加标题和文本段落,头部位于顶部,文本段落位于底部。以下是我们可以使用的 CSS:

      #featured-carousel li { overflow:hidden;list-style-type:none;position:relative;width:600px;height:400px; }
      #featured-carousel h4 { position:absolute;top:0;left:0;right:0;padding:10px;margin:0;color:#000;font-size:36px;text-shadow:#fff 0 0 1px; }
      #featured-carousel p { position:absolute;bottom:0;left:0;right:0;padding:10px;margin:0;color:#fff;background:#000;background:rgba(0,0,0,0.7); }
      
      

      现在,我的列表中的每个项目看起来都类似于以下的屏幕截图:

      行动时间 — 创建特色内容滑块

      我想要引起你对我在这里使用了一些方便的 CSS 技巧的注意。首先,请注意我给标题添加了一小段白色的text-shadow,并且将标题文本设为黑色。以防这段文本碰巧悬停在图片的黑色区域上,文本周围微妙的白色轮廓将帮助文本更加突出。然后,请注意,我为短段文本添加了两个背景值。第一个是纯黑色,第二个是使用rgba值表示的透明黑色。第一个值是针对 IE9 之前的版本的 Internet Explorer。这些浏览器将显示纯黑色的背景。更新的和更有能力的浏览器将使用第二个值,rgba值,在文本的后面显示略微透明的黑色背景—这样图片可以透过一点,同时使文本更易读。

    3. 现在,我们将会在页面底部,在 jQuery 和我们的scripts.js文件之间,附加 jCarousel JavaScript,就像我们在本章其他示例中所做的那样。

      <script src="img/jquery.js"></script>
      <script src="img/jquery.jcarousel.min.js"></script>
      <script src="img/scripts.js"></script>
      
      
    4. 现在我们要写一些 CSS 来自定义我们的内容滑块的外观。打开你的styles.css文件并添加以下样式:

      .jcarousel-skin-slider .jcarousel-container-horizontal { width: 600px; }
      .jcarousel-skin-slider .jcarousel-clip { overflow: hidden; }
      .jcarousel-skin-slider .jcarousel-clip-horizontal { width:600px;height:425px; }
      .jcarousel-skin-slider .jcarousel-item { width:600px;height:400px; }
      
      

      这就是全部了。只需几行代码。我们将设置单个项目、容器和剪辑容器的宽度为 600 像素,与一个图像的宽度相同。单个项目的高度也设置为 400 像素,但我们将把剪辑容器的高度设置为 425 像素,以便为我们添加一些外部控件提供 25 像素的空间,稍后我们会看到这些控件。

    5. 现在,打开你的scripts.js文件。我们首先要做的是选择我们的列表并将其存储在一个变量中。这是因为我们将多次使用列表,并且我们不希望 jQuery 每次都要查询 DOM 来查找我们的列表。

      var slider = $('#featured-carousel');
      
      
    6. 接下来,我们将设置我们的文档就绪语句,并在滑块上调用jcarousel()方法,并告诉它我们要一次滚动一个窗格。

      var slider = $('#featured-carousel');
      $(document).ready(function(){
      slider.jcarousel({
      scroll: 1
      });
      });
      
      
    7. 我们将添加我们自己的外部控件,因此我们需要删除jcarousel()方法自己创建的控件。我们可以这样做:

      $(document).ready(function(){
      slider.jcarousel({
      scroll: 1,
      buttonNextHTML: null,
      buttonPrevHTML: null	
      });
      });
      
      

      提供了buttonNextHTMLbuttonPrevHTML键,以便您可以为这些按钮指定自己的 HTML 标记。在这种情况下,我们将为这两个键传递null作为值,这将阻止它们被创建。

      现在我们已经完成了设置幻灯片放映器的基本操作。如果你在浏览器中查看页面,你会看到第一张幻灯片。我们还没有提供导航到其他幻灯片的方法,所以让我们立即解决这个问题。

      行动时间 —— 创建一个特色内容滑块

    分页控件

    我们设置了一个基本的滑块,一次显示一个项目,但你肯定已经注意到除了第一个之外,没有办法查看任何幻灯片。我们删除了 jCarousel 的默认下一个和上一个按钮,并且我们还没有提供任何替代方法。让我们添加一些分页控件,这样我们的网站访问者就可以查看任何他们喜欢的幻灯片。

    行动时间 —— 添加分页控件

    接下来,我们要设置一个函数,该函数将创建下一个按钮、上一个按钮和分页按钮,并使它们起作用。

    1. jCarousel 插件提供了一个名为initCallback的键,它允许我们传递一个应在轮播创建时调用的函数的名称。让我们通过创建一个空函数并调用它来开始:

      var slider = $('#featured-carousel');
      function carouselInit(carousel) {
      // Our function goes here
      }
      $(document).ready(function(){
      slider.jcarousel({
      scroll: 1,
      buttonNextHTML: null,
      buttonPrevHTML: null,
      initCallback: carouselInit	
      });
      });
      
      

      我们在carouselInit()函数中写的任何操作都将在轮播初始化或设置时执行。由于只有在启用 JavaScript 时,任何页码、上一个和下一个按钮才会起作用,所以我们想使用 JavaScript 动态创建这些按钮,而不是在 HTML 中编码它们。让我们看看如何创建一个包含滑块中每个幻灯片的页面链接列表。

    2. 我们将从获取滑块中的所有幻灯片开始。请记住,我们的滑块是一个无序列表,滑块中的每个幻灯片都是列表中的一个单独列表项。由于我们已经保存了对滑块本身的引用,因此我们可以如下获取其中的所有幻灯片:

      function carouselInit(carousel) {
      var slides = slider.find('li');
      }
      
      
    3. 我们将在稍后使用这些幻灯片来创建页面数字。但与此同时,我们需要一个放置页面数字的地方,所以让我们在幻灯片之前创建一些容器,这样我们的分页将显示在幻灯片正上方。下面是如何在幻灯片之前插入两个嵌套的<div>标签:

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      }
      
      
    4. 接下来,我们需要在我们的代码中几次引用这两个新创建的容器,所以我们将在变量中存储对它们的引用,如下面的代码所示:

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      var controls = $('#page-controls');
      var pages = $('#pages');
      }
      
      
    5. 现在,我们要高级一点,为幻灯片中的每一页创建一个页码。以下是我们要添加的代码:

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      var controls = $('#page-controls');
      var pages = $('#pages');
      for (i=1; i<=slides.length; i++) {
      pages.append('<a href="#">' + i + '</a>');
      }
      }
      
      

      我们从i = 1开始,因为第一页的页码将是 1。然后我们检查i是否小于或等于幻灯片的数量(slides.length是幻灯片的数量)。如果i小于或等于幻灯片的数量,我们将递增 i 一个数字——基本上我们将把 1 添加到i上,而i++是 JavaScript 中表示i = i+1的快捷方式。

      在每次循环中,我们都将在我们创建的页面容器中附加一个链接。它是围绕页码的链接,i 代表我们的页码。

      如果此时在浏览器中刷新页面,你将看到链接到幻灯片秀上面的数字 1 到 12。它们没有样式,并且点击它们不会做任何事情,因为我们还没有设置——这就是我们接下来要做的。

      操作时间 — 添加分页控件

    6. 接下来,我们要样式化链接,使它们看起来我们想要的样子。打开你的styles.css文件,添加下面几行到 CSS 中:

      #page-controls { line-height:25px;height:25px; }
      #page-controls a { margin:0 4px 0 0;padding:0 5px;border:1px solid #859900; }
      #page-controls a:hover { border-color: #D33682; }
      #page-controls a.current { color:#333;border-color:#333; }
      
      

      这将我们的幻灯片控制行的高度设置为之前允许的 25 个像素。然后我们在每个链接周围放置了一个绿色边框,当鼠标悬停在链接上时,它会变成粉红色边框。我们调整了边距和填充以获得间隔良好的盒子行。最后,我们为我们的链接添加了一个.current类,以便我们能够用深灰色标记当前选择的链接。

      操作时间 — 添加分页控件

    7. 好的,我们已经将页面数字添加到我们的文档中,所以我们所要做的就是让它们起作用。我们将为这些链接绑定一个点击函数,因为当我们的网站访客点击链接时我们希望发生一些事情。我们将如下开始:

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      var controls = $('#page-controls');
      var pages = $('#pages');
      for (i=1; i<=slides.length; i++) {
      pages.append('<a href="#">' + i + '</a>');
      }
      pages.find('a').bind('click', function(){
      //click code will go here
      });
      }
      
      
    8. 函数内的第一件事是取消点击的默认操作,这样浏览器在点击链接时不会尝试执行自己的操作。

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      var controls = $('#page-controls');
      var pages = $('#pages');
      for (i=1; i<=slides.length; i++) {
      pages.append('<a href="#">' + i + '</a>');
      }
      pages.find('a').bind('click', function(){
      return false;
      });
      }
      
      
    9. jCarousel 插件为我们提供了一个很好的方法来滚动到幻灯片中的特定幻灯片。看起来是这样的:

      carousel.scroll($.jcarousel.intval(number));
      
      

      结尾附近的numbers 是我们将要传递的幻灯片编号。例如,如果我们想滚动到第六张幻灯片,我们会这样说:

      carousel.scroll($.jcarousel.intval(6));
      
      

      在我们的情况下,我们要滚动到的数字幻灯片是链接中的页码。例如,如果我点击以下链接:

      <a href="#">3</a>
      
      

      这意味着我想要滚动到幻灯片中的第三张幻灯片。我可以使用 jQuery 的text()方法来获得该数字,如下所示:

      pages.find('a').bind('click', function(){
      carousel.scroll($.jcarousel.intval($(this).text()));
      return false;
      });
      
      

      如果我点击第四个链接,$(this).text()将等于 4;点击第七个链接,它将等于 7,以此类推。

      在浏览器中刷新页面,你会看到点击编号链接会将滑块滚动到该幻灯片。

    10. 点击页码时,您可能已经注意到当前页码未在分页中突出显示。我们已经编写了用于突出显示具有current类的链接的 CSS —— 现在我们只需确保我们正在向当前链接添加该类即可。以下是我们将如何做到这一点的方法。

      pages.find('a').bind('click', function(){
      carousel.scroll($.jcarousel.intval($(this).text()));
      $(this).addClass('current');
      return false;
      });
      
      

      现在,如果你在浏览器中刷新页面,你会发现点击页码会将current类 CSS 应用于链接,突出显示它。然而,点击第二个页码会突出显示该链接以及上一个链接。我们必须确保我们也从旧链接中移除类。添加以下行来处理这个问题:

      pages.find('a').bind('click', function(){
      carousel.scroll($.jcarousel.intval($(this).text()));
      $(this).siblings('.current').removeClass('current');
      $(this).addClass('current');
      return false;
      });
      
      

      此行检查所有链接的兄弟节点,查找是否有任何具有当前类的链接。如果找到任何一个,就移除该类。

    11. 现在,我们只需确保在轮播初始化时突出显示第一个链接即可。最简单的方法就是在创建轮播时简单地点击分页中的第一个链接,如下所示:

      pages.find('a').bind('click', function(){
      carousel.scroll($.jcarousel.intval($(this).text()));
      $(this).siblings('.current').removeClass('current');
      $(this).addClass('current');
      return false;
      }).filter(':first').click();
      
      

      记住,jQuery 允许我们链式调用方法——即使我们在bind()方法内写了一个完整的函数,我们仍然可以在其末尾链式调用 next 方法。我们调用filter()方法来将链接列表缩减为仅第一个链接,然后调用click()方法来触发我们刚刚绑定到链接的点击函数。

      现在,如果你在浏览器中刷新页面,你会看到第一个链接以我们当前类 CSS 突出显示。

      行动时间 —— 添加分页控件

    下一个和上一个按钮

    现在我们已经设置好了幻灯片和页码,但我们还想要简单的下一个和上一个按钮,以便轻松地逐页翻阅幻灯片。我们将在分页控件的两端添加它们。

    行动时间 —— 添加下一个和上一个按钮

    现在,我们只需要添加上一个和下一个按钮即可。

    1. 我们将在分页的开头添加上一个按钮,在结尾添加下一个按钮。以下是我们如何使用 jQuery 在文档中插入这些链接的方法:

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      var controls = $('#page-controls');
      var pages = $('#pages');
      for (i=1; i<=slides.length; i++) {
      pages.append('<a href="#">' + i + '</a>');
      }
      pages.find('a').bind('click', function(){
      carousel.scroll($.jcarousel.intval($(this).text()));
      $(this).siblings('.current').removeClass('current');
      $(this).addClass('current');
      return false;
      }).filter(':first').click();
      controls.prepend('<a href="#" id="prev">&laquo;</a>');
      controls.append('<a href="#" id="next">&raquo;</a>');
      }
      
      

      我已经使用prepend()方法将上一个按钮插入到页码之前,并使用append()方法将下一个按钮插入到页码之后。

      如果你在浏览器中刷新页面,你会看到下一个和上一个按钮以及我们的分页按钮显示出来。

      行动时间 —— 添加下一个和上一个按钮

      然而,点击它们不会引起任何事情发生——我们必须连接这些按钮以使它们起作用。我们从下一个按钮开始。

    2. 就像分页按钮一样,我们需要绑定点击事件。同样,jCarousel 插件为我们提供了一个很好的方法来切换到下一张幻灯片。

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      var controls = $('#page-controls');
      var pages = $('#pages');
      for (i=1; i<=slides.length; i++) {
      pages.append('<a href="#">' + i + '</a>');
      }
      pages.find('a').bind('click', function(){
      carousel.scroll($.jcarousel.intval($(this).text()));
      $(this).siblings('.current').removeClass('current');
      $(this).addClass('current');
      return false;
      }).filter(':first').click();
      controls.prepend('<a href="#" id="prev">&laquo;</a>');
      controls.append('<a href="#" id="next">&raquo;</a>');
      $('#next').bind('click', function() {
      carousel.next();
      return false;
      });
      }
      
      

      我们选择下一个按钮并绑定了一个点击事件。我们取消了浏览器的默认操作,以便在单击链接时浏览器不会尝试执行任何操作。然后,我们所要做的就是调用carousel.next(),jCarousel 将负责帮我们前进到下一个幻灯片。

      在浏览器中刷新页面,您会发现单击下一个按钮会将滑块向前移动一个幻灯片。

      您还会注意到,分页中当前突出显示的页面未更新。让我们看看如何解决这个问题。

    3. 我们将通过以下方式开始找到当前突出显示的页码:

      $('#next').bind('click', function() {
      carousel.next();
      var current = pages.find('.current');
      return false;
      });
      
      

      在这里,我们只是在我们的页码中查找具有current类的页码。

    4. 接下来,我们将移除current类,移动到下一个页面编号链接,并将current类添加到该链接中,如下所示:

      current.removeClass('current').next().addClass('current');
      
      

      啊,但不要那么快,我们只想在有下一个链接要跳转时才这样做。如果没有,那么我们就什么也不想做。如果我们检查current.next(). length,我们就可以判断是否有下一个链接。因此,我们只需将此代码块包装在一个if语句中,如下所示的代码所示:

      if ( current.next().length ) { current.removeClass('current').next().addClass('current'); }
      
      

      现在,如果您在浏览器中刷新页面,您会发现下一个按钮按预期工作。当我们到达最后一页时,它不会做任何事情,正如我们所预期的那样。

    5. 现在我们将使用与前一个按钮非常相似的函数重复整个过程。以下是它的样子:

      $('#prev').bind('click', function(){
      carousel.prev();
      var current = pages.find('.current');
      if ( current.prev().length ) { current.removeClass('current').prev().addClass('current'); }
      return false;
      });
      
      

      这是我们完整的carouselInit()函数的样子:

      function carouselInit(carousel) {
      var slides = slider.find('li');
      slider.before('<span id="page-controls"><span id="pages"></span></span>');
      var controls = $('#page-controls');
      var pages = $('#pages');
      for (i=1; i<=slides.length; i++) {
      pages.append('<a href="#">' + i + '</a>');
      }
      pages.find('a').bind('click', function(){
      carousel.scroll($.jcarousel.intval($(this).text()));
      $(this).siblings('.current').removeClass('current');
      $(this).addClass('current');
      return false;
      }).filter(':first').click();
      controls.prepend('<a href="#" id="prev">&laquo;</a>');
      controls.append('<a href="#" id="next">&raquo;</a>');
      $('#prev').bind('click', function(){
      carousel.prev();
      var current = pages.find('.current');
      if ( current.prev().length ) { current.removeClass('current').prev().addClass('current'); }
      return false;
      });
      $('#next').bind('click', function() {
      carousel.next();
      var current = pages.find('.current');
      if ( current.next().length ) { current.removeClass('current').next().addClass('current'); }
      return false;
      });
      }
      
      

      现在,如果您在浏览器中刷新页面,您会发现下一个和上一个按钮都按预期工作,连同页面编号。您可以使用这些外部控件导航到幻灯片中的任何幻灯片。

      执行操作的时间——添加下一个和上一个按钮

    刚才发生了什么?

    我们设置了 jCarousel 每次显示一个幻灯片。我们确保 jCarousel 没有创建自己的下一个和上一个按钮。我们使用 jQuery 向我们的文档添加了下一个、上一个和分页按钮,然后使用 jCarousel 的有用方法从这些外部控件控制幻灯片。我们确保当前显示的幻灯片在分页中突出显示,以便我们的网站访问者可以轻松地看到他们在幻灯片中的位置。

    轮播幻灯片

    现在我们已经学会了如何设置控制幻灯片的外部控件,让我们也以相同的方式设置幻灯片来控制幻灯片。在本节中,我们将创建一个简单的交叉淡入淡出幻灯片,由缩略图图像的轮播控制。以下是我们将要创建的示例的样本:

    轮播幻灯片

    点击轮播内任何缩略图都会在幻灯片区域加载出该图像的大尺寸版本。我也在幻灯片旁边提供了下一个和上一个按钮,让网站访问者可以逐个点击图片而不必单击每个缩略图来通过幻灯片放映中途。让我们看看如何将其放在一起。

    行动时间-创建一个缩略图幻灯片

    设置轮播缩略图幻灯片将是我们使用 jCarousel 做过的最困难的事情。但不要担心,我们会一步一步来。

    1. 我敢打赌,你能猜到我们要如何开始,对吧?没错,通过设置我们简单的 HTML 文件和相关的文件和文件夹,就像我们在第一章 设计师,遇见 jQuery中做的一样。在这种情况下,我们只想要一个简单的缩略图列表,它们链接到图像的全尺寸版本。并且我们将将其包裹在一个<div>中进行样式设置。这就是我的列表是什么样子的:

      <div class="jcarousel-skin-slideshow">
      <ul id="thumb-carousel">
      <li><a href="images/600/Switzerland.jpg"><img src="img/Switzerland.jpg" alt="Switzerland"/></a></li>
      <li><a href="images/600/CostaRica.jpg"><img src="img/CostaRica.jpg" alt="Costa Rica"/></a></li>
      <li><a href="images/600/Canada.jpg"><img src="img/Canada.jpg" alt="Canada"/></a></li>
      ...
      </ul>
      </div>
      
      

      我的列表中总共有十二个项目,并且它们都具有相同的标记。

    2. 接下来,我们将为轮播图编写 CSS。这是一个定制设计,所以我们不会包含 jCarousel 提供的样式表之一。打开你的styles.css文件,并添加以下 CSS:

      .jcarousel-skin-slideshow .jcarousel-container { }
      .jcarousel-skin-slideshow .jcarousel-container-horizontal { width:760px;padding:0 48px; }
      .jcarousel-skin-slideshow .jcarousel-clip { overflow:hidden; }
      .jcarousel-skin-slideshow .jcarousel-clip-horizontal { width:760px;height:75px; }
      .jcarousel-skin-slideshow .jcarousel-item { width:100px;height:75px; }
      .jcarousel-skin-slideshow .jcarousel-item-horizontal { margin-left:0;margin-right:10px; }
      .jcarousel-skin-slideshow .jcarousel-item-placeholder { background:#fff;color:#000; }
      .jcarousel-skin-slideshow .jcarousel-next-horizontal { position:absolute;top:0;right:0;width:38px;height:75px;cursor:pointer;background:transparent url(images/arrow-right.png) no-repeat 0 0; }
      .jcarousel-skin-slideshow .jcarousel-next-horizontal:hover,
      .jcarousel-skin-slideshow .jcarousel-next-horizontal:focus { background-position:0 -75px; }
      .jcarousel-skin-slideshow .jcarousel-next-horizontal:active { background-position: 0 -75px; }
      .jcarousel-skin-slideshow .jcarousel-prev-horizontal { position:absolute;top:0;left:0;width:38px;height:75px;cursor:pointer;background:transparent url(images/arrow-left.png) no-repeat 0 0; }
      .jcarousel-skin-slideshow .jcarousel-prev-horizontal:hover,
      .jcarousel-skin-slideshow .jcarousel-prev-horizontal:focus { background-position: 0 -75px; }
      .jcarousel-skin-slideshow .jcarousel-prev-horizontal:active { background-position: 0 -75px; }
      
      

      我已经创建了一个图片精灵,其中包含了我的下一个和上一个按钮的图片,并且这就是它们的背景图片所使用的。其余的部分应该看起来很熟悉 - 为每个项目和轮播图本身设置适当的尺寸。

    3. 现在,我们将在文档底部,在 jQuery 和你的scripts.js文件之间,附加 jCarousel 插件:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.jcarousel.min.js"></script>
      <script src="img/scripts.js"></script>
      
      
    4. 打开你的scripts.js文件,我们将通过在文档就绪语句内选择轮播并调用jcarousel()方法来启动我们的缩略图轮播。

      $(document).ready(function(){
      $('#thumb-carousel').jcarousel({
      scroll: 6,
      wrap: 'circular'
      });
      });
      
      

      我们已经将值'circular'分配给了wrap键-这意味着轮播没有开始也没有结束-它将在网站访问者滚动时不断地环绕。

    连续包裹很好-我们的网站访问者可以点击向前或向后的轮播按钮,无论他们身在何处,这比禁用按钮更友好一些。然而,连续滚动可能会使我们的网站访问者更难以跟踪他们在轮播中的位置。因此,尽管我们的轮播能够显示七张图片,我们已经将滚动设置为6

    假设我们的网站访问者正在查看我们的轮播,并且在轮播的第一个位置有一张美丽的海滩风景照片。网站访问者点击了上一个按钮,而那美丽的海滩风景照片滑过来填补了轮播的最后一个位置。在新位置看到同一张图片有助于传达刚刚发生的事情,并确保我们的网站访问者没有错过任何事情。

    行动时间 — 创建缩略图幻灯片

    刚才发生了什么?

    我们按照了我们在早期 jCarousel 示例中所做的类似步骤。设置了我们的 HTML,为轮播器编写了一些 CSS 样式,然后使用 jQuery 选择了缩略图列表,并调用了jCarousel()方法。现在,让我们更进一步,向我们的轮播器添加幻灯片。

    幻灯片

    现在我们已经设置好了我们想要的简单轮播器并对其进行了样式化,让我们深入了解如何添加淡入淡出幻灯片特效。

    行动时间 — 添加幻灯片

    jCarousel 插件已经为我们设置了轮播器,但我们想要变得花哨,并且还要添加一个幻灯片区域。

    1. 我们现在独自一人,所以我们将为创建幻灯片区域创建一个单独的函数。然后我们将在我们的文档就绪语句中调用新函数:

      function slideshowInit() {
      // Slideshow setup goes here
      }
      $(document).ready(function(){
      slideshowInit();
      $('#thumb-carousel').jcarousel({
      scroll: 6,
      wrap: 'circular'
      });
      });
      
      
    2. 首先,我们将在缩略图列表周围包裹一个容器,以创建幻灯片区域。我们发现自己已经需要再次引用缩略图列表,所以让我们将其存储在一个变量中,并更新对jcarousel()方法的调用如下:

      var thumbs = $('#thumb-carousel');
      function slideshowInit() {
      // Slideshow setup goes here
      }
      $(document).ready(function(){
      slideshowInit();
      thumbs.jcarousel({
      scroll: 6,
      wrap: 'circular'
      });
      });
      
      
    3. 接下来,在slideshowInit()函数内部,我们将调用 jQuery 的wrap()方法将列表包裹在一个<div>中。

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      }
      
      
    4. 接下来,我们需要创建实际的舞台,全尺寸图像将在其中显示。我们还需要创建下一个和上一个按钮。我们将使用prepend()方法,以便这些元素在缩略图列表之前被插入到stage-wrap div中。

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      $('#stage-wrap').prepend('<div id="slideshow-next"></div><div id="slideshow-prev"></div><div id="stage"></div>');
      }
      
      
    5. 现在,我们将回到我们的styles.css文件,并为这些新元素添加一些样式,如下所示:

      #stage-wrap { position:relative;width:856px; }
      #stage { width:600px;height:400px;padding:0 0 20px 0;position:relative;text-align:center;margin:0 128px; }
      #stage img { position:absolute;top:0;left:50%;margin-left:-300px; }
      #slideshow-next { position:absolute;right:80px;top:160px;width:38px;height:75px;cursor:pointer;background:transparent url(images/arrow-right.png) no-repeat 0 0; }
      #slideshow-next:hover,
      #slideshow-next:active { background-position:0 -75px; }
      #slideshow-prev { position:absolute;left:80px;top:160px;width:38px;height:75px;cursor:pointer;background:transparent url(images/arrow-left.png) no-repeat 0 0; }
      #slideshow-prev:hover,
      #slideshow-prev:active { background-position:0 -75px; }
      
      

      所有的全尺寸图像都是相同大小的,600x400,所以我们可以将其设置为舞台的宽度和高度,并相应地定位下一个和上一个图像按钮。如果您现在在浏览器中查看页面,您应该会看到为舞台留下的大空白区域,以及缩略图轮播器上方的下一个和上一个图像按钮,所有这些都位于其上方。

      行动时间 — 添加幻灯片

    6. 我们有一个轮播器,我们有一个空舞台,我们在舞台两侧有下一个和上一个按钮。接下来,我们将用图像幻灯片填充舞台。我们将通过设置一个变量来引用舞台,并将舞台的opacity设置为0来开始,如下所示的代码:

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      $('#stage-wrap').prepend('<div id="slideshow-next"></div><div id="slideshow-prev"></div><div id="stage"></div>');
      var stage = $('#stage');
      stage.css('opacity',0);
      }
      
      

      我们隐藏了舞台,以便我们可以在不让站点访问者看到图像加载的情况下将图像加载到其中。这让我们能够在创建幻灯片时对其外观有一些控制。在有东西可看之前,我们将保持舞台不可见。

    7. 接下来,我们需要获取所有到全尺寸图像的链接,并准备好查找每个全尺寸图像的 URL,如下所示:

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      $('#stage-wrap').prepend('<div id="slideshow-next"></div><div id="slideshow-prev"></div><div id="stage"></div>');
      var stage = $('#stage');
      stage.css('opacity',0);
      var imageLinks = thumbs.find('a');
      var src;
      }
      
      

      全尺寸图像的链接包含在缩略图列表中,我们可以用thumbs变量引用它们。我们只是找到该列表中的所有链接,并将它们存储在一个名为imageLinks的变量中。接下来,我们设置一个名为src的空容器,我们将在其中存储图像的 URL。尽管目前,我们将该容器留空。我们稍后会填充它。

    8. 我们有 12 个全尺寸图像的链接。对于每个链接,我们需要在舞台上创建一个新图像。我们将使用 jQuery 的each()方法循环遍历每个链接并创建一个图像。

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      $('#stage-wrap').prepend('<div id="slideshow-next"></div><div id="slideshow-prev"></div><div id="stage"></div>');
      var stage = $('#stage');
      stage.css('opacity',0);
      var imageLinks = thumbs.find('a');
      var src;
      imageLinks.each(function(i) {
      // We'll create our images here
      });
      }
      
      

      这是 jQuery 的方式说对于每个链接,执行此操作

    9. 接下来,我们将为每个链接创建一个图像。首先,我们知道图像的src属性将等于链接的href属性。换句话说,链接如下所示:

      <a href="images/600/Switzerland.jpg">Switzerland</a>
      
      

      将用于创建如下图像:

      <img src="img/Switzerland.jpg"/>
      
      

      所以我们要做的第一件事是获取之前创建的空src变量,并将图像的 URL 存储在其中:

      imageLinks.each(function(i) {
      src = $(this).attr('href');
      });
      
      

      接下来,我们将使用这个src属性创建一个图像。我将把我新创建的图像存储在一个名为img的变量中:

      imageLinks.each(function(i) {
      src = $(this).attr('href');
      var img = $('<img/>', {
      src: src,
      css: {
      display: 'none'
      }
      });
      });
      
      

      我们将图像的显示设置为 none,以隐藏以这种方式创建的所有图像。我们已将图像的src属性设置为保存图像 URL 的src变量。

    10. 现在图像已创建,我们将其添加到舞台上。

      imageLinks.each(function(i) {
      src = $(this).attr('href');
      var img = $('<img/>', {
      src: src,
      css: {
      display: 'none'
      }
      });
      img.appendTo(stage);
      });
      
      

      jQuery 的appendTo()方法允许我们将图像附加到舞台上。

    11. 现在舞台上充满了图像,让我们继续使其可见。

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      $('#stage-wrap').prepend('<div id="slideshow-next"></div><div id="slideshow-prev"></div><div id="stage"></div>');
      var stage = $('#stage');
      stage.css('opacity',0);
      var imageLinks = thumbs.find('a');
      var src;
      imageLinks.each(function(i) {
      src = $(this).attr('href');
      var img = $('<img/>', {
      src: src,
      css: {
      display: 'none'
      }
      });
      img.appendTo(stage);
      });
      stage.css('opacity',1);
      }
      
      
    12. 接下来,我们想要在单击轮播中的缩略图链接时在舞台上显示相应的图像。如果现在单击缩略图,你会发现它会在浏览器中打开全尺寸图像,但我们希望图像显示在舞台上。我们只需要一种方式来从轮播中的图像引用舞台上的特定图像。我们可以通过几种不同的方式来做到这一点,几乎总是有多种方法可以完成某事。在这种情况下,我们将利用 jQuery 的data()方法在每个缩略图链接中存储索引号。然后我将使用该索引来找到并显示适当的图像。

      基本上,我们要对列表中的链接进行编号。你可能会认为它们会被编号为 1 到 12,但请记住 JavaScript 计数从 0 开始,因此缩略图图像将被编号为 0 到 11。当单击缩略图时,我们将获取该缩略图的索引号,找到舞台上具有相同索引的图像并显示它。所以如果我们的网站访客单击缩略图编号为 6,我们将在舞台上找到编号为 6 的图像并显示它。

      首先,我们必须为缩略图分配索引号。在文档就绪声明中,添加一个小函数来循环遍历每个缩略图,并添加索引号,如下所示:

      $(document).ready(function(){
      thumbs.find('a').each(function(index){
      $(this).data('index', (index));
      });
      slideshowInit();
      thumbs.jcarousel({
      scroll: 6,
      wrap: 'circular',
      initCallback: nextPrev
      });
      });
      
      
    13. 现在所有的缩略图链接都已经编号,我们可以编写一个函数,在点击缩略图时找到舞台上适当的图像并显示它。在slideshowInit()函数内部,我们将把我们的函数绑定到点击事件上:

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      $('#stage-wrap').prepend('<div id="slideshow-next"></div><div id="slideshow-prev"></div><div id="stage"></div>');
      var stage = $('#stage');
      stage.css('opacity',0);
      var imageLinks = thumbs.find('a');
      var src;
      imageLinks.each(function(i) {
      src = $(this).attr('href');
      var img = $('<img/>', {
      src: src,
      css: {
      display: 'none'
      }
      });
      img.appendTo(stage);
      });
      stage.css('opacity',1);
      imageLinks.bind('click', function(){
      // Function to find and show an image goes here
      });
      }
      
      
    14. 在我们的新功能内部要做的第一件事是取消浏览器的默认行为。我们不希望链接在浏览器中打开图像,所以我们会返回 false。

      imageLinks.bind('click', function(){
      return false;
      })
      
      
    15. 接下来,我们需要获取我们链接中存储的数字。我们将再次使用data()方法来找到这个数字:

      imageLinks.bind('click', function(){
      var index = $(this).data('index');
      return false;
      })
      
      
    16. 现在,我们需要在舞台上搜索具有该索引号的图像。我将把图像存储在一个名为nextImage的变量中,因为它将是要显示的下一个图像。

      imageLinks.bind('click', function(){
      var index = $(this).data('index');
      var nextImage = stage.find('img:eq(' + index + ')');
      })
      
      

      jQuery 允许我们使用:eq选择器按索引号查找元素。例如,$('img:eq(1)')选择器会选择图像列表中的第二个图像。(记住,JavaScript 计数从 0 开始,而不是从 1 开始。)在这种情况下,我知道我想要哪个数字图像,因为它是刚刚点击的链接中存储的数字。

    17. 现在我们已经得到了下一个图像,我们需要显示它。我们将淡入它并添加一个active类。

      imageLinks.bind('click', function(){
      var index = $(this).data('index');
      var nextImage = stage.find('img:eq(' + index + ')');
      nextImage.fadeIn().addClass('active');
      return false;
      })
      
      
    18. 但是不要忘记,已经有另一张图像可见。我们需要找到那张图像并将其淡出。由于我们在图像显示时添加了一个active类,所以我们可以通过查找具有active类的图像轻松找到当前显示的图像:

      imageLinks.bind('click', function(){
      var index = $(this).data('index');
      var nextImage = stage.find('img:eq(' + index + ')');
      stage.find('img.active').fadeOut().removeClass('.active');
      nextImage.fadeIn().addClass('active');
      return false;
      })
      
      

      不要忘记,我们必须确保删除那个active类,以便一次只有一个图像被标记为活动状态。

    如果你现在在浏览器中刷新页面,你会看到点击幻灯片缩略图链接中的任意一个会在幻灯片中加载相应的图像。一张图像淡出,而下一张图像以一种流畅的方式淡入。接下来,我们将让下一个和上一个按钮工作起来,这样我们就可以轻松地翻转到下一个图像。

    刚才发生了什么?

    哎呀!希望你还在继续跟着我,因为这是向你的网站访问者展示幻灯片的一种非常棒的方式。希望你开始意识到,有时候插件只是一个开始 — 你可以发挥创造力,发明自己的功能来叠加在默认插件行为之上。

    下一个和上一个按钮

    我们确实取得了一些不错的进展。点击缩略图会在幻灯片中加载图像的全尺寸版本,我们可以使用幻灯片控件滚动缩略图并查看它们所有。现在,让我们让下一个和上一个图像按钮起作用。

    行动时间 —— 激活下一个和上一个按钮

    接下来,我们将让围绕图像的下一个和上一个按钮工作起来,这样网站访问者可以轻松地翻阅所有的图像。

    1. 就像我们在上一个示例中为幻灯片连接外部控制一样,我们将从设置幻灯片的回调函数开始。我们将函数命名为nextPrev并设置如下:

      function nextPrev(carousel) {
      }
      thumbs.jcarousel({
      scroll: 6,
      wrap: 'circular',
      initCallback: nextPrev
      });
      
      

      现在nextPrev函数将在旋转木马初始化时被调用。

    2. nextPrev()函数内部,我们将选择上一个按钮并绑定一个函数到点击事件:

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      //Click code will go here
      });
      }
      
      
    3. 当站点访问者点击上一个按钮时,我们希望显示幻灯片秀中的前一幅图像。与 JavaScript 一般一样,有多种方法可以实现这一点。由于我们已经设置好了一个好用的幻灯片切换功能,当旋转木马中的其中一个缩略图被点击时发生,让我们直接重复使用它。

      当我们的站点访问者点击上一个按钮时,我们会找到旋转木马中的上一个缩略图并点击它。这将启动图像过渡,并允许我们重复使用我们已经编写的代码。

      因此,我们的首要任务是找到当前选择的缩略图。但是,我们并没有简化找到当前缩略图的方法。因此,让我们回到slideshowInit()函数内部,并添加一行代码将一个类添加到当前的缩略图上:

      function slideshowInit() {
      thumbs.wrap('<div id="stage-wrap"></div>');
      $('#stage-wrap').prepend('<div id="slideshow-next"></div><div id="slideshow-prev"></div><div id="stage"></div>');
      var stage = $('#stage');
      stage.css('opacity',0);
      var imageLinks = thumbs.find('a');
      var src;
      imageLinks.each(function(i) {
      src = $(this).attr('href');
      var img = $('<img/>', {
      src: src,
      css: {
      display: 'none'
      }
      });
      img.appendTo(stage);
      });
      stage.css('opacity',1);
      imageLinks.bind('click', function(){
      var index = $(this).data('index');
      $(this).parents('li').addClass('current').siblings('.current').removeClass('current');
      var nextImage = stage.find('img:eq(' + index + ')');
      stage.find('img.active').fadeOut().removeClass('.active');
      nextImage.fadeIn().addClass('active');
      return false;
      })
      }
      
      

      在这里,我们给包含点击缩略图的<li>标签添加了一个current类。然后,我们检查所有兄弟元素,以移除current类(如果它存在的话)。这确保了在任何给定时间内,旋转木马中只有一个项目具有current类。

    4. 现在,如果您能给我一个分钟,我们将进行一个旁支到 CSS。由于我们正在向当前缩略图添加一个类,我们可以利用 CSS 来对当前缩略图进行样式设置,使其与其他不同。让我们打开styles.css并添加一些样式如下:

      #thumb-carousel img { opacity:.5; }
      #thumb-carousel .current img { opacity:1; }
      
      
    5. 回到 JavaScript!现在我们有一种简单的方法来选择当前的缩略图,我们只需找到具有current类的缩略图即可。在prevNext()函数内部,我们可以通过以下方式获取当前链接:

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      });
      }
      
      
    6. 由于这是附加到上一个按钮的功能,我们需要找到列表中的上一个缩略图。我将使用 jQuery 的prev()方法在旋转木马中找到上一个缩略图:

      currentSlide.prev();
      
      

      然而,如果当前幻灯片是第一张,那就没有上一个幻灯片可供查看。在这种情况下,如果站点访问者在第一张幻灯片上并单击上一个按钮,我希望他们跳转到列表中的最后一张幻灯片,以便无缝续播。因此,我首先要检查是否有上一张幻灯片如下:

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      var prevSlide = currentSlide.prev().length ? currentSlide.prev() : thumbs.find('li:last');
      });
      }
      
      

      这里有几件事情要解释。首先,这行代码从 JavaScript 翻译成英语说这个缩略图之前有一个吗?如果有的话,那就是我们要去的地方。如果没有,那么我们将前往最后一个缩略图。

      var prevSlide;
      if (currentSlide.prev().length) {
      prevSlide = currentSlide.prev();
      } else {
      prevSlide = thumbs.find('li:last');
      }
      
      

      以下是三元运算符的工作原理:

      condition to check ? value if true : value if false
      
      

      它以我们正在检查的条件开始,后跟一个?。之后,我们有如果该条件为真,则跟随的值,后跟一个:,以及如果该条件为假则跟随的值。

    7. 现在我们找到了上一个幻灯片,剩下的就是点击其中的链接如下:

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      var prevSlide = currentSlide.prev().length? currentSlide.prev() : thumbs.find('li:last');
      prevSlide.find('a').click();
      });
      }
      
      

      这将触发我们编写的在浏览器中更改幻灯片的函数。如果此时在浏览器中重新加载页面,然后点击几次前一个按钮,你会看到图片会像我们预期的那样切换。

      但是,轮播图上并没有太多的事情。它就那么呆在那里。而且马上当前选定的缩略图就看不见了。如果我点击一次前一个按钮,然后滚动轮播图,最终我才能看到高亮的缩略图。理想情况下,轮播图会更新自身,以确保当前缩略图始终可见。

    8. jCarousel 插件使我们可以轻松地滚动到轮播图中的任何幻灯片。我们只需要知道我们想要显示哪一个。jCarousel 的设置脚本的一部分还为轮播图中的每个列表项分配了一个 jcarouselindex 属性。我们可以获取该数字并将其用于滚动目的。首先,让我们弄清楚 prevSlidejcarouselindex 是多少,因为那是我们想要滚动到的位置。

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      var prevSlide = currentSlide.prev().length? currentSlide.prev() : thumbs.find('li:last');
      var index = parseInt(prevSlide.attr('jcarouselindex'));
      prevSlide.find('a').click();
      });
      }
      
      

      我使用parseInt()来确保我得到一个数字而不是一个字符串。如果我得到一个字符串,它可能会搞乱轮播图中的滚动。

      现在,剩下的就是滚动到正确的缩略图:

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      var prevSlide = currentSlide.prev().length? currentSlide.prev() : thumbs.find('li:last');
      var index = parseInt(prevSlide.attr('jcarouselindex'));
      prevSlide.find('a').click();
      carousel.scroll(index);
      });
      }
      
      

      现在,如果你在浏览器中刷新页面,你会看到点击前一个按钮会更新轮播图——轮播图会滚动,以使当前高亮的幻灯片成为轮播图中的第一张。但是,如果我决定希望当前高亮的幻灯片出现在中间呢?很简单!我有七张幻灯片显示。如果高亮的幻灯片在中间,那么在它之前会有三张幻灯片(以及它之后的三张)。我所要做的就是告诉轮播图将高亮幻灯片的前三张幻灯片设为第一张可见的幻灯片,如下所示:

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      var prevSlide = currentSlide.prev().length? currentSlide.prev() : thumbs.find('li:last');
      var index = parseInt(prevSlide.attr('jcarouselindex')) - 3;
      prevSlide.find('a').click();
      carousel.scroll(index);
      });
      }
      
      

      现在,例如,当我点击前一个按钮时,如果下一张幻灯片是第 5 张,轮播图将首先显示第 2 张,这意味着第 5 张将出现在轮播图的中间。在浏览器中刷新页面,试一试。很棒,对吧?

    9. 唯一剩下的就是使下一个按钮像前一个按钮一样工作。函数几乎相同,只需做一些微调。

      function nextPrev(carousel) {
      $('#slideshow-prev').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      var prevSlide = currentSlide.prev().length? currentSlide.prev() : thumbs.find('li:last');
      var index = parseInt(prevSlide.attr('jcarouselindex')) - 3;
      prevSlide.find('a').click();
      carousel.scroll(index);
      });
      $('#slideshow-next').bind('click', function() {
      var currentSlide = thumbs.find('li.current');
      var nextSlide = currentSlide.next().length ? currentSlide.next() : thumbs.find('li:first');
      var index = parseInt(nextSlide.attr('jcarouselindex')) - 3;
      nextSlide.find('a').click();
      carousel.scroll(index);
      });
      }
      
      

      我使用next()方法而不是prev()方法来获取下一张幻灯片而不是上一张。除此之外,函数是相同的。

    现在,如果你在浏览器中刷新页面,你会看到下一个和前一个图片按钮都可以使用——它们会显示幻灯片秀中的正确图片,并滚动轮播图,以使当前图片在轮播图的中间高亮显示。

    刚才发生了什么?

    我们将一些外部的轮播控制与幻灯片放在一起,创建了一个强大的幻灯片/轮播组合。幻灯片可以从轮播控制——点击轮播中的缩略图将在幻灯片舞台中加载出完整尺寸的图像。并且点击舞台中的下一个和上一个按钮将更新轮播,滚动轮播,以便当前高亮的缩略图出现在轮播的可见区域中间。

    我们从一些基本的 HTML 开始,为轮播编写了自定义的 CSS 皮肤,并调用了 jcarousel() 方法来使轮播工作。接下来,我们编写了一个函数来动态创建幻灯片舞台和按钮。最后,我们通过一些精巧的 jQuery 操作使它们都能协同工作。

    总结

    我们研究了在各种情况下使用 jCarousel 插件的方法,我们创建了一个简单的水平缩略图轮播,一个垂直新闻滚动条,一个带有外部控制的特色内容滑块,最后,一个展示了 jCarousel 插件功能的轮播/幻灯片组合。现在,你在工具箱中又增加了一个强大的工具——jCarousel 插件是灵活、强大的,并且可以定制以适用于各种不同的情况。

    接下来,我们将看一下创建交互式数据表格。

    第十一章:创建交互式数据网格

    虽然你可能认为数据网格并不那么令人兴奋,但它们确实为站点访问者提供了一种与大量数据交互并理解数据的方式,这是他们可能无法以其他方式做到的。HTML5 中最令人兴奋的发展之一是引入了网格元素,它允许我们仅使用标记就能轻松创建交互式数据网格。然而,它是新元素之一,浏览器支持落后——目前几乎没有或几乎没有任何浏览器支持,并且可能需要数年时间,我们才能利用这个新元素。幸运的是,我们可以使用 jQuery 来填补这一空白,直到新的网格元素准备就绪。

    在本章中,我们将学习以下主题:

    • 使用 Allan Jardine 的 DataTables jQuery 插件将普通表格转换为交互式数据网格

    • 使用 jQuery UI Themeroller 对数据网格的外观和行为进行定制

    基本数据网格

    我们将使用 DataTables 插件创建一个基本的数据网格,保留默认设置和数据网格提供的样式。当我们有大量数据要呈现时,数据网格是最有帮助的,并且站点访问者可能希望以不同的方式过滤和排序数据,以找到他们正在寻找的信息。例如,想象一下航班列表——一个站点访问者可能有兴趣按出发时间对航班进行排序,以找到可能的最早出发时间,而另一个站点访问者可能想按持续时间对航班进行排序,以找到可能的最短航班。

    将数据呈现为交互式数据网格允许每个站点访问者在海量信息中快速轻松地找到他们正在寻找的信息。对于禁用 JavaScript 的站点访问者,他们将只看到一张大型数据表,永远不会知道他们错过了交互式功能。所有信息仍然对他们可用。

    行动时间——创建基本数据网格

    让我们看看如何将基本的 HTML 表格转换为交互式数据网格:

    1. 我们将像在第一章 设计师,见 jQuery 中一样,使用我们的基本 HTML 文件和相关文件和文件夹开始。我们将使用 HTML 标记来填充我们的 HTML 文档的<body>部分,创建一个大型数据表的 HTML 标记。DataTables 插件要求我们对表格标记进行仔细且正确的处理。我们需要确保为表格的标题使用一个<thead>元素,并为表格的主体使用一个<tbody>元素。可选的为表格页脚使用一个<tfoot>元素。以下是一个所有时间最畅销书籍的表格的 HTML 标记的简化样本:

      <table id="book-grid">
      <thead>
      <tr>
      <th>Title</th>
      <th>Author</th>
      <th>Original Language</th>
      <th>First Published</th>
      <th>Approximate Sales</th>
      </tr>
      </thead>
      <tbody>
      <tr>
      <td>A Tale of Two Cities</td>
      <td>Charles Dickens</td>
      <td>English</td>
      <td>1859</td>
      <td>200 million</td>
      </tr>
      <tr>
      <td>Le Petit Prince (The Little Prince)</td>
      <td>Antoine de Saint-Exup&eacute;ry</td>
      <td>French</td>
      <td>1943</td>
      <td>200 million</td>
      </tr>
      ...
      </tbody>
      </table>
      
      

      我已经向表格中添加了共计 106 本书,每本都像这样标记。请注意,我们在表格元素上添加了一个idbook-grid的 id,并使用了<th>元素来作为每列的标题,并将其封装在<thead>元素中。我们还使用了一个<tbody>元素来包装表格主体中的所有行。

    2. 接下来,我们将下载 DataTables 插件。前往datatables.net,在那里你会找到插件的下载、文档和示例。点击页眉中的下载链接下载 ZIP 文件。执行操作的时间——创建基本数据表

    3. 解压文件夹并查看其内部。执行操作的时间——创建基本数据表

      • 有一个examples文件夹,其中包含几个不同的 DataTables 插件示例。一个extras文件夹提供了高级数据表的额外功能,我们这里不会使用任何其中的东西。有一个media文件夹,其中包含images、css、jsunit_testing资源。最后还有一个Readme.txt文件,其中包含有关插件创建者和文档位置等信息。

        最后,你会找到插件的许可证,包括 BSD 和 GPL。你可以阅读这些许可证文件或访问维基百科获取这些许可证的详细信息,但它们都是允许你免费使用插件代码的自由软件许可证。

    4. 我们将建立一个基本示例,所以我们只需要为我们自己的项目准备一些东西。首先,将images目录的内容复制到你自己的images目录中。打开css文件夹,将demo_table.css复制到你自己的styles目录中。要小心选择正确的 CSS 文件demo_table.css,因为那里有几个 CSS 文件。最后,在js文件夹中,找到插件的压缩版本jquery.dataTables.min.js,并将其复制到你自己的scripts目录中。

    5. 接下来,我们将获取所有必要的文件附加到包含我们表格的 HTML 页面中。在文档的<head>部分,在你自己的styles.css文件之前附加 CSS 文件:

      <link rel="stylesheet" href="styles/demo_table.css"/>
      <link rel="stylesheet" href="styles/styles.css"/>
      
      
    6. 接下来,在 HTML 文档的底部,在 jQuery 和你自己的scripts.js文件之间附加 DataTables 插件:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.dataTables.min.js"></script>
      <script src="img/scripts.js"></script>
      </body>
      </html>
      
      
    7. 接下来,打开你的scripts.js文件,并在文档准备就绪的语句中,选择表格并调用dataTable()方法,如下所示:

      $(document).ready(function(){
      $('#book-grid').dataTable();
      });
      
      

      现在,如果你在浏览器中刷新页面,你会看到你的表已经被转换成了数据表格。你可以选择一次查看多少项,输入到搜索框中以查找特定的表项,并使用右下角的分页控件浏览数据表的行。

      执行操作的时间——创建基本数据表

    刚才发生了什么?

    我们设置了一个基本的 HTML 表格,并通过附加一些 CSS 和 DataTables 插件将其转换为交互式数据表。我们选择了表格并调用了 dataTable() 方法以激活 DataTables 插件。

    这很容易,不是吗?当然,这种淡紫色设计可能不符合您网站的设计,所以让我们看看如何自定义数据表的外观。

    自定义数据表

    DataTables 插件是我们使用的第一个具有 jQuery UI Themeroller 支持的插件。jQuery UI 是一组小部件和交互,使构建复杂应用程序变得更容易更快。学习 jQuery UI 本身超出了本书的范围,但我们将看看如何使用 jQuery UI Themeroller 为我们的数据表创建自定义主题。这个主题将适用于我们页面上使用的任何 jQuery UI 小部件,以及任何包含 jQuery UI Themeroller 支持的 jQuery 插件。

    行动时间 — 自定义数据表

    我们将从上次的数据表结束的地方继续。如果您想保存您的基本示例,只需保存文件的副本。然后按照以下步骤自定义数据表的外观:

    1. 转到 jqueryui.com/themeroller ,我们将看看 Themeroller。在左列中,您会找到选择预定义主题或创建自定义主题的控件,而宽广的右列包含几种不同类型小部件的示例。行动时间 — 自定义数据表

    2. 在左列中单击 Gallery 选项卡 ,您会看到有数十种预构建的 Themeroller 主题可供选择。当您单击不同示例时,您将看到右列中的示例小部件更新以反映该样式。我通常喜欢从选择一个与我想要的颜色方案或外观相当接近的预构建主题开始,然后切换到 Roll Your Own 选项卡 进行微调以满足我的需求。对于这个示例,我将从 Cupertino 风格开始。

      在切换到 Roll Your Own 选项卡 后,您会看到有关字体、颜色、角落、标题等的设置。进行任何您想要的调整,使主题看起来符合您的喜好。请随意玩耍和尝试。如果您走得太远,得到了您不喜欢的东西,那么轻松地切换回 Gallery 选项卡 并重新选择预构建主题,剥离掉您的任何自定义内容,然后重新开始。

      请记住,如果重新选择预构建主题,您的任何自定义内容都将丢失。一旦您得到喜欢的东西,请务必继续进行第 3 步以保存它。

    3. 一旦您将主题设置得符合您的喜好,只需单击 下载主题 按钮。行动时间 — 自定义数据表

    4. 您将会发现自己在 构建您的下载 页面上,可能会有点困惑。请注意,jQuery UI 是如此庞大,提供了如此多的不同功能,开发人员意识到强迫每个人下载整个内容是不合理的。如果您只想使用一个小部件,那么就没必要下载所有其他小部件和效果。这个页面让您选择不同的 jQuery UI 组件,这样您就不必下载您不需要的内容。

      由于我们只需要一个主题,所以我们可以放心地点击页面顶部的 取消选择所有组件 链接。

      行动时间 — 自定义数据网格

      • 然后,我们将离开 主题版本 设置为默认值,并点击 下载 按钮下载一个 ZIP 文件。
    5. 解压文件并查看其中内容。您会看到即使我们得到了最简单的下载,我们仍然有相当多的文件。行动时间 — 自定义数据网格

      • 我们有一个包含我们的主题文件夹、一个 CSS 文件和 图像css 文件夹。我们还有一个 development-bundle 文件夹、一个 HTML 文件和一个包含 jQuery 和 jQuery UI 文件的 js 文件夹。

        我们所需的全部内容就是我们的主题。将您的主题文件夹复制到您自己项目的 styles 目录中。我的主题文件夹被命名为 cupertino,因为那是我选择的主题。如果您选择了不同的主题,您的主题文件夹将被命名为其他内容。不过很容易找到,因为它将是 css 文件夹内唯一的文件夹。

    6. 接下来,我们将把我们的主题 CSS 文件附加到我们的 HTML 文件中。在<head>部分内,将您的主题 CSS 文件附加到我们在上一个示例中附加的 demo_table.css 文件之前。

      <link rel="stylesheet" href="styles/cupertino/jquery-ui-1.8.16.custom.css"/>
      <link rel="stylesheet" href="styles/demo_table.css"/>
      
      
    7. 不幸的是,我们的主题 CSS 文件并没有包含我们所需的所有样式来美化数据网格。毕竟,jQuery UI 的开发人员无法知道人们将要使用的所有不同类型的小部件和插件,所以他们不可能覆盖每种情况。幸运的是,DataTables 插件作者 Allan Jardine 在这方面已经为我们做了一些很好的工作,并提供了一个包含我们所需样式的 CSS 文件,以使我们的主题数据网格看起来更好。

      您可以在 Allan Jardine 在 datatables.net/styling/ 上提供的文档中了解如何为 DataTables 插件设置样式。

      回到 DataTables 插件文件内部,打开 media 文件夹内的 css 文件夹,找到 demo_table_jui.css 文件。将其复制到您自己的 styles 文件夹中,并更新您的 <link> 标签,以链接到这个版本的 demo_table.css,如下所示:

      <link rel="stylesheet" href="styles/cupertino/jquery-ui-1.8.16.custom.css"/>
      <link rel="stylesheet" href="styles/demo_table_jui.css"/>
      
      
    8. 现在我们只需对 JavaScript 代码进行小小的更新。我们必须告诉dataTable()方法,我们要使用 jQuery UI。返回到您的scripts.js文件,我们将添加一对花括号,并传递一个键/值对以启用我们的数据表的 jQuery UI 样式:

      $(document).ready(function(){
      $('#book-grid').dataTable({
      'bJQueryUI': true
      });
      });
      
      

      如果您现在在浏览器中刷新页面,您会看到数据网格现在使用了与我们在 jQuery UI 主题页面上看到的部件一致的样式:

      行动时间-自定义数据网格

      • 但您会注意到,表格行的颜色方案仍然是薰衣草色。
    9. 让我们对颜色方案进行一些调整。打开demo_table_jui.css。只需更新几行。首先,我们将找到第 281 行,那里定义了表格斑马条纹的颜色,并将其更新为我们想要使用的颜色,如下所示:

      tr.odd {
      background-color: #f1f7fb;
      }
      tr.even {
      background-color: white;
      }
      
      

      我选择淡蓝色作为奇数行的颜色,白色作为偶数行的颜色,与我之前选择的 Cupertino 样式相匹配。随意选择与您的选择的主题相匹配的颜色。

    10. 接下来,我们将更改当前排序行的颜色方案。你会在第 380 行找到已排序的奇数行的 CSS。我将把我的改成中蓝色,如下所示:

      tr.odd td.sorting_1 {
      background-color: #d6e7f4;
      }
      
      
    11. 最后,我们可以找到 CSS 中已排序的偶数行在第 392 行。我要把它改成浅蓝色。

      tr.even td.sorting_1 {
      background-color: #e4eff8;
      }
      
      

      您可以选择与自己选择的主题协调的颜色。

      现在,如果您在浏览器中刷新页面,您会看到表格的斑马条纹图案与我们的主题相匹配。

      行动时间-自定义数据网格

    12. 接下来,我们将看看对数据网格进行其他一些自定义。首先,让我们将这些简单的下一页和上一页的分页按钮改成数字。我们将传递另一个键/值对给dataTable方法,以将按钮替换为分页数字,如下所示:

      $(document).ready(function(){
      $('#book-grid').dataTable({
      'sPaginationType': 'full_numbers',
      'bJQueryUI': true
      });
      });
      
      

      注意

      记住每个键/值对之间要用逗号分隔,但不要在最后一个键/值对之后加逗号。

      • 如果您在浏览器中刷新页面,您会看到简单的按钮已被替换为分页数字,如下图所示:

      行动时间-自定义数据网格

    13. 我们可能会决定,对于这个特定的数据表,搜索功能并不合适。DataTables 插件提供了一种方法来禁用单个功能。要禁用搜索框过滤,我们将传递另一个键/值对,如下所示:

      $(document).ready(function(){
      $('#book-grid').dataTable({
      'sPaginationType': 'full_numbers',
      'bJQueryUI': true,
      'bFilter': false
      });
      });
      
      

      在浏览器中刷新页面,您会看到搜索框消失了。

      行动时间-自定义数据网格

    14. 您可能已经注意到,默认情况下,DataTables 插件按升序将我们的表按第一列排序,从 A 到 Z。在某些情况下,这可能是可以接受的,但在这种情况下,由于我们正在列出有史以来最畅销的书籍,我们可能想要对表进行排序,以便首先显示销售量最高的书籍。我们将传入一个新的键值对来指定默认排序应使用哪一列以及排序应该采用的方向。

      $(document).ready(function(){
      $('#book-grid').dataTable({
      'sPaginationType': 'full_numbers',
      'bJQueryUI': true,
      'bFilter': false,
      'aaSorting': [[4, 'desc']]
      });
      });
      
      

      我们正在使用的键称为'aaSorting',值是列号和排序方向,位于两组方括号内。不要忘记 JavaScript 是从 0 开始计数的,而不是从 1 开始计数。因此,我们表格中的第五列实际上是第 4 列。然后,我们希望将最高的数字放在顶部,所以我们传递 'desc' 表示降序排序。

      在浏览器中刷新页面,你会发现图书现在按销售量从高到低的顺序排列。同时,请注意,这种默认排序方式不影响您网站访问者根据任何其他列以任何顺序对表进行排序的能力。访客仍然可以与您的表进行交互。我们只是以最合理的方式重新定义了默认视图,以便呈现我们正在呈现的数据。

    刚刚发生了什么?

    我们将我们的基本数据网格提升了一步,通过定制插件的外观和行为。我们学会了如何使用 jQuery UI Themeroller 创建我们数据网格的自定义主题。然后,我们学会了如何用页码替换简单的分页按钮,禁用搜索表,以及如何为数据网格设置默认排序。

    摘要

    在本章中,我们学会了如何将普通的 HTML 表格转变为交互式数据网格。我们的网站访问者现在可以利用对表的不同列进行排序的功能以不同的方式查看数据。禁用 JavaScript 的网站访问者只会看到包含所有数据的普通 HTML 表格。数据网格并不是非常令人兴奋,但它们可以使您的网站访问者更轻松地处理大量数据。接下来,我们将学习如何使表单既更漂亮又更易于使用。

    第十二章:改善表单

    如果你曾经尝试过使用网络表单,你就知道它们可以是多么令人头疼。幸运的是,HTML5 的作者们正在努力确保这种体验得到改善。我们都在耐心地等待浏览器支持那些不错的新功能,但与此同时,我们必须建立站点并制作出漂亮且功能良好的表单。

    在本章中,您将学习以下主题:

    • 使用一些新的 HTML5 属性标记一个表单

    • 将光标放在第一个表单字段中

    • 在表单字段中使用占位符文本

    • 验证您网站访客的表单输入

    • 设计样式顽固的表单元素,如文件上传和选择下拉框

    一个 HTML5 网络表单

    我们将利用 HTML5 中提供给我们的一些新属性开始。这些增加的好处在于它们完全向后兼容。不了解如何处理它们的浏览器将要么忽略它们,要么默认为简单的文本输入,而我们网站上的老式浏览器访客甚至可以在不知道自己错过什么的情况下使用我们的表单。

    首先,关于网络表单的一个警告。一个网络表单不能单独工作 —— 它需要在某个服务器上进行一些花哨的后端编程来收集表单条目并处理它们,无论是将字段写入数据库还是通过电子邮件发送表单信息。因此,在点击表单上的 提交 按钮后,本章中构建的表单实际上不会起作用 —— 什么也不会发生。

    如果您想要在项目中添加一个可用的网络表单,您有几个选择。它们如下:

    • 您可以学习进行服务器端编程来处理您的表单,但服务器端编程远远超出了本书的范围。

    • 您可以使用 CMS,它可能会将表单处理作为其核心功能或作为附加功能之一。好的候选包括 Drupal、WordPress 和 Joomla!。

    • 您可以雇用一个服务器端开发人员来使您的表单工作。或者与一个交朋友,用您的设计技能交换他们的编码技能。

    • 您可以使用网络表单服务来处理您表单的所有服务器端处理。我个人最喜欢的是 WuFoo,我已经使用了多年而且没有出现过任何问题。(wufoo.com)

    任何这些方法都将帮助您创建一个可包含在您的项目中的工作表单。但是,让我们看看如何使我们的表单的前端尽可能好。

    行动时间 —— 设置 HTML5 网络表单

    1. 我们将从一个简单的 HTML 文档和关联的文件和文件夹开始,就像我们在第一章中设置的那样,设计师,见 jQuery。我们要确保在文档顶部的文档类型声明中使用 HTML5 文档类型:

      <!DOCTYPE html>
      
      

      在 HTML 4 和 xHTML 中使用的所有长而复杂的文档类型声明之后,这个声明简直是一股清新的空气,不是吗?

    2. 现在,在<body>标签内,按照以下方式打开一个<form>标签:

      <form action="#" id="account-form">
      </form>
      
      

      form标签需要一个action属性才能工作。由于我们的表单只是用于脚本和样式目的的虚拟表单,我们将使用#作为该属性的值。action属性的值通常是一个 URL——我们将发送表单数据进行处理的服务器上的位置。我们还添加了一个id属性,以便稍后轻松选择表单用于 CSS 和 JavaScript 目的。

    3. 接下来,我们将为我们的网站访问者创建一个用户名和密码的部分。我们将把这两个字段放在一个fieldset中,并使用一个legend将它们组合起来。

      <form action="#" id="account-form">
      <fieldset>
      <legend>My Account</legend>
      <p>
      <label for="username">Username</label>
      <input type="text" name="username" id="username"/>
      </p>
      <p>
      <label for="password">Password</label>
      <input type="password" name="password" id="password"/>
      </p>
      </fieldset>
      </form>
      
      

      我用段落标签(<p>)包装了每个字段及其相关的标签。关于用什么标签标记您的表单字段,世界上有各种各样的意见。有些开发人员喜欢简单的<div>标签,而其他人喜欢将表单制作为列表(<ul>),每个字段为列表项(<li>)。其他人喜欢使用定义列表(<dl>),将标签放在<dt>标签内,将表单字段放在<dd>标签内。归根结底,这些任何一种都可以很好地完成任务,并且您的表单将按预期为您的网站访问者工作。使用您个人偏好的任何标签。

      仔细看看我们到目前为止为我们的表单编写的 HTML 标记。有一些重要的事情需要注意。它们如下:

      • 每个<input>type与其用途相关。用户名具有text类型,而密码具有password类型。

      • 每个<input>都有一个唯一的id。请记住,id在页面上必须是唯一的,因此请谨慎选择您的表单输入的id

      • 每个<input>都有一个name属性。这将传递给服务器端处理您的表单的任何代码。通常的做法是为表单元素的nameid使用相同的值,但这不是强制性的。您可以随时为id选择不同的值,但如果您想更改name值,您应该首先与您的服务器端开发人员核实他或她编写的代码是否仍然有效。

      • 每个<label>都有一个for属性,将其与特定的表单元素关联起来。for属性中的值等于与之关联的表单元素的id(而不是name)。这为我们的网站访问者提供了一些很好的功能,点击标签将聚焦于相关的表单元素。这种行为对于复选框和单选按钮输入特别有用,因为它们很小,可能很难点击。

        每个浏览器都有自己的方式来为表单元素设置样式,但这是我的我的账户部分的样式(在 Mac OSX 上的 Google Chrome 中):

      行动时间——设置 HTML5 网络表单

    4. 接下来,我们将为我们的表单创建一个关于我部分。

      <fieldset>
      <legend>About Me</legend>
      <p>
      <label for="name">Name</label>
      <input type="text" name="name" id="name"/>
      </p>
      <p>
      <label for="email">Email address</label>
      <input type="email" name="email" id="email"/>
      </p>
      <p>
      <label for="website">Website</label>
      <input type="url" name="website" id="website"/>
      </p>
      <p>
      <label for="birthdate">Birth Date</label>
      <input type="date" name="birthdate" id="birthdate"/>
      </p>
      </fieldset>
      
      

      同样,Name输入使用了text类型,因为名称是字符串。然而,看一下Email、WebsiteBirth Date字段的type属性。我们在这里使用了新的 HTML5 输入类型。在不支持这些输入类型的浏览器中,这些字段将看起来和使用text类型的输入框一样工作。但在识别这些输入类型的浏览器中,它们的行为会有所不同。用户输入将被浏览器自动验证。例如,如果站点访客在具有email类型的输入框中输入一个无效的电子邮件地址,浏览器会警告他们输入了一个无效的电子邮件地址。

      此外,在具有软键盘的设备上,键盘键将被更改以反映输入该数据类型所需的字符。例如,在 iPhone 或 iPad 上,具有email类型的输入将打开一个键盘,显示.@,这样使得您的站点访客在这些设备上更容易完成所需的信息输入。

      执行动作的时间——设置 HTML5 网络表单

    5. 我表单中的下一部分将是有关饮料偏好的部分。我希望站点访客从列表中选择他们喜欢的饮料,然后回答一个关于他们每年喝多少天饮料的问题。以下是我的列表样本:

      <fieldset>
      <legend>Beverage Info</legend>
      <fieldset>
      <legend>Select your favorite beverages</legend>
      <p>Select at least three and no more than six beverages</p>
      <ul>
      <li>
      <input type="checkbox" name="favorites[]" id="bev-water" value="bev-water"/>
      <label for="bev-water">Water</label>
      </li>
      <li>
      <input type="checkbox" name="favorites[]" id="bev-juice" value="bev-juice"/>
      <label for="bev-juice">Juice</label>
      </li>
      </ul>
      </fieldset>
      <p>
      <label for="days">How many days per year do you drink a beverage?</label>
      <input type="number" name="days" id="days"/>
      </p>
      </fieldset>
      
      

      执行动作的时间——设置 HTML5 网络表单

      关于我们用于标记此部分的 HTML 的一些新内容如下:

      • Fieldsets可以嵌套。fieldset是将一组复选框或单选按钮分组的绝佳方式,我们可以使用fieldsetlegend来为我们的单选按钮或复选框组创建标题。

      • 一组复选框之所以被识别为复选框,是因为它们将共享相同的name。由于站点访客可以在一组复选框中选择多个项目,因此我们在名称的末尾添加方括号([]),以便服务器将所有答案收集到一个数组中。

      • 集合中的每个复选框都有自己独特的idvalueidvalue不一定要匹配,但通常很容易使它们相同。

      • 最后,每年的天数被赋予了number类型的输入,因为这里只接受数字。对于此输入类型要小心。它非常严格,不会接受任何非数字字符。一些数据位看起来是数字,但实际上是字符串,比如电话号码和信用卡号。如果您不打算对您的数字执行某种数学操作,那么它不应该是number输入类型。

    6. 我们将添加到表单中的下一个部分是支付信息部分:

      <fieldset>
      <legend>Payment Info</legend>
      <fieldset>
      <legend>Credit Card Type</legend>
      <ul>
      <li>
      <input type="radio" name="cc-type" id="cc-visa" value="cc-visa"/>
      <label for="cc-visa">Visa</label>
      </li>
      <li>
      <input type="radio" name="cc-type" id="cc-mastercard" value="cc-mastercard"/>
      <label for="cc-mastercard">Mastercard</label>
      </li>
      <li>
      <input type="radio" name="cc-type" id="cc-amex" value="cc-amex"/>
      <label for="cc-amex">American Express</label>
      </li>
      <li>
      <input type="radio" name="cc-type" id="cc-discover" value="cc-discover"/>
      <label for="cc-discover">Discover</label>
      </li>
      </ul>
      </fieldset>
      <p>
      <label for="cc-number">Credit card number</label>
      <input type="text" name="cc-number" id="cc-number"/>
      </p>
      </fieldset>
      
      

      就像复选框一样,我们在fieldset内分组了一组单选控件,legend充当了该部分的标题。与复选框类似,一组单选控件共享相同的名称,但每个控件都有自己独特的id和值。但是,在单选按钮的情况下,只能选择一个,所以不需要将它们标记为数组。

      我们还添加了一个字段,用于收集我们站点访问者的信用卡号码。请注意,我们将此字段的输入类型设置为text。即使信用卡号看起来是一个数字,我们也希望将它存储为它本来的样子,永远不会对这个数字进行加减操作。此外,客户可能希望在他们的信用卡号中输入空格或连字符。

      行动时间——设置 HTML5 网页表单

    7. 最后,我们将添加一个复选框,供我们的站点访问者接受我们的服务条款,并添加一个提交按钮,让他们向我们提交表单信息。

      <fieldset>
      <ul>
      <li>
      <input type="checkbox" name="tos" id="tos" value="tos"/>
      <label for="tos">Click here to accept our terms of service</label>
      </li>
      </ul>
      <p>
      <input type="submit" value="Sign me up!"/>
      </p>
      </fieldset>
      
      

      这里唯一的新东西就是提交按钮。默认情况下,带有submit类型的输入框将显示提交。我们可以通过添加一个带有实际想要出现在按钮上的文本的value属性来更改它。

      行动时间——设置 HTML5 网页表单

    8. 唯一剩下的事情就是用一点 CSS 为我们的表单添加样式。以下是我为我的简单表单使用的 CSS:

      fieldset { width:400px;margin:0;padding:10px;border:1px solid #c1c3e6;background:#f1f2fa;margin-top:10px; }
      fieldset fieldset { border:0 none;border-top:1px solid #c1c3e5;border-bottom:1px solid #c1c3e5;width:380px;margin-bottom:10px; }
      legend { padding:3px 5px;color:#6c71c4;font-weight:bold;font-size:1.2em; }
      fieldset fieldset legend { font-size:1em;font-weight:normal; }
      fieldset p { margin: 0 0 10px 0; }
      fieldset ul { margin:0;padding:0;list-style:none; }
      label { display:inline-block;width:150px; }
      ul label { display:inline;width:auto; }
      input[type="text"],
      input[type="password"],
      input[type="email"],
      input[type="url"],
      input[type="date"],
      input[type="number"] { width:150px;border:1px solid #c1c3e6;padding:4px; }
      
      

      注意我们输入框的type属性可用于选择它们进行样式设置。在这种情况下,我已经将它们全部样式设置为相同,但如果需要的话,也可以为每个输入框设置自己的样式。

      这是我的 CSS 样式的表单外观。随意发挥创造力,为表单编写你自己的样式。

      行动时间——设置 HTML5 网页表单

    刚才发生了什么?

    我们看了一些新的 HTML5 输入类型以及如何正确使用它们来组合一个网页表单。我们了解了如何使用fieldsetlegend来将字段组合在一起并添加标题,以及如何将标签与表单元素关联起来。我们学习了文本、密码、电子邮件、URL、日期、复选框、单选按钮和数字输入类型的正确使用。

    设置焦点

    如果你访问google.com,你会发现他们让你很容易进行网页搜索——只要页面在浏览器中加载完成,光标就会在搜索字段中闪烁。还有其他一些网站也是这样做的,这样就可以快速轻松地开始填写表单。

    每当你有一个页面,站点访问者在该页面的主要任务是填写表单时,你都可以通过将光标放在第一个表单字段中来为站点访问者提供便利。使用 jQuery 很容易实现。以下是如何做的。

    行动时间——将焦点设置到第一个字段

    我们将继续使用上一个示例中设置的示例表单进行操作。以下是如何将焦点设置到表单中的第一个字段。

    1. 打开你的空白scripts.js文件,并添加一个文档就绪的声明。

      $(document).ready(function(){
      //code goes here
      });
      
      
    2. 接下来,我们想要选择表单中的第一个字段。有许多不同的方法可以做到这一点。在这种情况下,我将使用第一个表单元素的id

      $(document).ready(function(){
      $('#username');
      });
      
      
    3. 剩下的就是调用那个元素的focus()方法。

      $(document).ready(function(){
      $('#username').focus();
      });
      
      

      现在,如果你在浏览器中刷新页面,你会看到光标在表单的用户名字段中闪烁——正是第一个字段。

    刚才发生了什么?

    我们使用了几行 jQuery 代码来将焦点移动到表单中的第一个字段,这样我们的网站访问者可以轻松地开始填写表单。只需选择第一个表单元素,然后调用该元素的focus()方法即可。

    占位文本

    当你访问一个网站时,有一个软灰色的文本在表单字段中给你一些提示,这不是很好吗?过去几年里已经写了无数不同的 jQuery 插件来处理这个问题,因为这可能有点麻烦。

    但是,我有个好消息要告诉你。HTML5 提供了一个placeholder属性,可以自动在表单字段中创建这种文本,而无需 JavaScript 的帮助。当然,与任何其他尖端技术一样,浏览器支持可能有些欠缺。我们没有等待多年让浏览器支持这一新功能变得普遍——我们现在就必须构建功能性的网站。你可以继续使用所有那些旧的 jQuery 插件,但如果支持 placeholder 属性,为什么不利用它,并只在那些尚未识别它的浏览器中使用 jQuery 来填补空白呢?

    这种脚本称为polyfill。它用于填补一些浏览器可能缺少的功能。如果浏览器支持placeholder属性,polyfill 脚本就什么都不做,只是让浏览器处理占位符。对于那些不支持placeholder属性的网站访问者,脚本会立即生效,为所有人提供占位文本功能。

    是时候行动起来了——添加占位文本

    按照以下步骤,为尽可能多的网站访问者添加表单字段的占位文本,无论他们的浏览器是否支持新的 HTML5 占位属性。

    1. 我们将继续使用我们在前两节中构建的相同表单。我们首先要做的是重新检查每个表单字段,并在合适的地方添加一个占位属性。以下是我的表单中的一些示例:

      <p>
      <label for="username">Username</label>
      <input type="text" name="username" id="username" placeholder="At least 5 characters long"/>
      </p>
      
      

      在这里,我增加了关于用户名所需长度的提示。

      <p>
      <label for="password">Password</label>
      <input type="password" name="password" id="password" class="required" placeholder="Choose a secure password"/>
      </p>
      
      

      因为再怎么说都不嫌多,我在这里提醒我的网站访问者创建一个安全的密码。

      <p>
      <label for="website">Website</label>
      <input type="url" name="website" id="website" placeholder="Don't forget the http://"/>
      </p>
      
      

      提醒网站访问者,有效的 URL 包括开头的协议。

      <p>
      <label for="birthdate">Birth Date</label>
      <input type="date" name="birthdate" id="birthdate" placeholder="yyyy-mm-dd"/>
      </p>
      
      

      任何时候一个字段需要特殊格式,占位文本都可以为网站访问者提供提示。

      当你添加完占位符文本后,可以在 Safari 或 Chrome 中查看你的页面,以查看占位符文本的效果。

      行动时间——添加占位符文本

      • 现在我们需要为那些尚未支持占位符文本的浏览器添加支持。
    2. 我们将使用丹·本特利(Dan Bentley)的占位符兼容性补丁。要下载它,只需访问 github.com/danbentley/placeholder。就像我们从 GitHub 下载的其他插件一样,点击 ZIP 按钮下载一个压缩文件夹。行动时间——添加占位符文本

    3. 解压文件夹并查看其内容。这是一个非常简单直接的插件。行动时间——添加占位符文本

      • 您有一个样本 index.html 文件,一个 style.css 文件和一个 jquery.placeholder.js 文件,以及一个许可证和一个自述文件。
    4. 有关此插件的好消息是,它只需在页面上存在即可发挥其魔力。将 jquery.placeholder.js 复制到您自己的 scripts 文件夹中。然后,转到页面底部,并在 jQuery 之后、您自己的 scripts.js 文件之前将脚本附加到页面上:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.placeholder.js"></script>
      <script src="img/scripts.js"></script>
      
      

      现在,如果您在不支持占位符属性的浏览器中打开页面,您将看到占位符正常工作。这些浏览器是 Firefox 3.6 及更低版本,Safari 3 及更低版本,Internet Explorer 9 及更低版本以及 Opera 10 及更低版本。

    刚刚发生了什么?

    我们使用了丹·本特利的占位符兼容性补丁来为不支持的浏览器添加占位符支持。我们在适当的地方给表单字段添加了 placeholder 属性,然后在我们的页面上包含了丹的脚本,以使这些占位符属性在尽可能多的浏览器中工作。

    验证用户输入

    有时,当网站访问者不得不多次提交表单来纠正他们填写的错误时,他们可能会感到沮丧。没有 JavaScript,验证网站访问者输入的信息的唯一方法是等待他们提交表单,然后在服务器上识别问题,并返回一个包含表单以及可能帮助网站访问者纠正问题的任何错误消息的页面。

    一旦出现错误,立即显示错误将大大提高您的表单的灵活性和响应性,并帮助您的网站访问者在第一次尝试时正确提交表单。在本节中,我们将学习如何使用 Jörn Zaefferer 的验证插件。此插件功能强大且灵活,可以以多种不同的方式处理验证。我们将看一下将客户端验证添加到您的表单中最简单的方法。

    行动时间——即时验证表单值

    我们将继续使用我们在过去三个部分中创建的表单。按照以下步骤验证用户对表单的输入:

    1. 我们要做的第一件事是下载验证插件并将其附加到我们的页面上。

      前往bassistance.de/jquery-plugins/jquery-plugin-validation/,并在Files部分点击Download按钮下载 ZIP 文件。

      行动时间——动态验证表单值

    2. 打开 ZIP 文件并看看我们得到了什么。行动时间——动态验证表单值

      • 这里有很多内容。几个不同的 JavaScript 文件,一个更改日志等等。记得我说过这个插件功能强大,可以处理各种各样的验证方法吗?这就是所有这些的用途。处理几乎任何你可能遇到的旧的疯狂的验证情况。

        幸运的是,我们的情况相当简单,所以我们不需要做任何复杂的事情。

    3. jquery.validate.min.js复制到您自己的scripts文件夹并将其附加到您的页面。

      <script src="img/jquery.js"></script>
      <script src="img/jquery.placeholder.js"></script>
      <script src="img/jquery.validate.min.js"></script>
      
      

      在这种情况下,占位符脚本与验证脚本之间没有依赖关系,因此它们出现的顺序不重要,只要它们都在 jQuery 之后即可。

    4. 接下来,我们将回顾一下我们的表单,并添加一些验证插件将使用的信息。让我们从用户名字段开始:

      <p>
      <label for="username">Username</label>
      <input type="text" name="username" id="username" placeholder="At least 5 characters long" minlength="5" maxlength="20" class="required"/>
      </p>
      
      

      这是一个必填字段——任何填写此表单的网站访问者都必须选择一个用户名,所以我只需添加一个classrequired。如果我愿意,我可以使用该类名为此表单字段创建特殊的样式。即使我不这样做,验证也会使用此信息确保此字段已填写。

      接下来,所有用户名必须介于 5 到 20 个字符之间。所以我添加了minlengthmaxlength属性。

    5. 接下来是密码字段,它也是必填的。所以我会添加所需的类。

      <p>
      <label for="password">Password</label>
      <input type="password" name="password" id="password" class="required" placeholder="Choose a secure password"/>
      </p>
      
      

      顺便说一句,我也会在电子邮件字段中添加所需的类。

      <p>
      <label for="email">Email address</label>
      <input type="email" name="email" id="email" placeholder="you@example.com" class="required"/>
      </p>
      
      
    6. 接下来,让我们看一下喜爱饮料的列表。记得我们在那里给网站访问者留了一条注释,要求他们至少选择三种但不要超过六种?我们实际上可以通过验证插件来强制执行。进入系列中的第一个复选框并添加minlengthmaxlength属性,如下所示:

      <li>
      <input type="checkbox" name="favorites[]" id="bev-water" value="bev-water" maxlength="6" minlength="3"/>
      <label for="bev-water">Water</label>
      </li>
      
      

      我们只需要在第一个复选框上添加这个,而不是所有的复选框。验证足够智能,可以理解我们谈论的是这组复选框。

    7. 现在,让我们看一下我们询问网站访问者每年喝多少天饮料的领域。显然,一年只有 365 天,这是他们可以在这个领域输入的最高数字。所以我们会添加一个max属性来指定最高可能的数字。

      <p>
      <label for="days">How many days per year do you drink a beverage?</label>
      <input type="number" name="days" id="days" max="365"/>
      </p>
      
      
    8. 这将我们带到了支付部分。无论我们在卖什么,它都不是免费的,所以我们将要求输入信用卡类型和信用卡号。要求输入单选按钮,我们只需要在一组中的第一个单选按钮中添加required类。

      <li>
      <input type="radio" name="cc-type" id="cc-visa" value="cc-visa" class="required"/>
      <label for="cc-visa">Visa</label>
      </li>
      
      

      我们不必对单选按钮系列进行任何其他更改。

    9. 现在,让我们处理信用卡号本身。我们需要添加required类。我们还需要添加一个creditcard类来验证输入的号码实际上是一个有效的信用卡号。

      <p>
      <label for="cc-number">Credit card number</label>
      <input type="text" name="cc-number" id="cc-number" placeholder="xxxxxxxxxxxxxxxx" class="creditcard required"/>
      </p>
      
      
    10. 而在我们的表单底部,有我们的服务条款复选框。这也是必需的,所以我们将添加required类。

      <li>
      <input type="checkbox" name="tos" id="tos" class="required" value="tos"/>
      <label for="tos">Click here to accept our terms of service</label>
      </li>
      
      
    11. 现在,我们只需要调用 Validation 使我们可以使用的validate()方法。在你的文档准备好的声明中,选择表单并调用validate()方法。

      $(document).ready(function(){
      $('#username').focus();
      $('#account-form').validate();
      });
      
      
    12. 现在,如果您在浏览器中刷新页面,您将看到您无法在没有填写任何内容的情况下提交表单 - 必填字段将被标记为错误消息,说明该字段是必需的。如果您尝试在网站电子邮件地址字段中输入无效的网址或电子邮件地址,您将收到一条错误消息,让您知道需要纠正的问题。只是一个问题,这些错误消息在我们的复选框和单选按钮的位置有点奇怪。动作时间-即时验证表单值

      • 那实际上并不能帮助人们准确理解发生了什么。幸运的是,Validation 允许我们在页面上添加自己的错误消息,无论我们想要它们显示在哪里。
    13. 我们将在信用卡类型单选按钮列表后添加错误消息。

      <li>
      <input type="radio" name="cc-type" id="cc-discover" value="cc-discover"/>
      <label for="cc-discover">Discover</label>
      </li>
      </ul>
      <label for="cc-type" class="error">Select a credit card type!</label>
      </fieldset>
      
      

      我们将添加一个<label>。在这种情况下,for 属性将指向字段的name,所有单选按钮共享cc-type名称。我们将添加一个错误类,并在内部添加我们想要的任何error消息。

      注意,在这种情况下,我们的labelfor属性指的是字段的name,而不是 ID。这是 Validation 插件创建的特殊情况。如果你不是使用 Validation 插件的自定义错误消息,那么你的标签的for属性应该始终引用表单元素的id

    14. 接下来,我们不希望这些错误消息出现在页面上,除非它们是需要的。我们也希望它们以红色显示,这样它们就很显眼,易于找到。打开你的styles.css文件,为错误消息添加一些样式:

      label.error { display:none;width:360px;color:#dc522f;margin-top:5px; }
      
      

      我们添加了一个宽度,因为我已经将我的其他标签设置为短并且浮动到左侧。并且我们添加了一点边距,为了在错误消息和它所指的字段之间添加一些空间。

      现在如果你刷新浏览器,并尝试在没有选择信用卡类型的情况下提交表单,你将得到一个更好的错误消息位置,如下所示:

      动作时间-即时验证表单值

    15. 接下来,我们需要为我们喜爱的饮料和我们的服务条款复选框做同样的事情:这是我们将添加的喜爱的饮料:

      <li>
      <input type="checkbox" name="favorites[]" id="bev-wine" value="bev-wine"/>
      <label for="bev-wine">Wine</label>
      </li>
      </ul>
      <label for="favorites[]" class="error">Please select at least three and no more than six favorite beverages</label>
      </fieldset>
      
      

      这是我们将添加的服务条款:

      <fieldset>
      <ul>
      <li>
      <input type="checkbox" name="tos" id="tos" class="required"/>
      <label for="tos">Click here to accept our terms of service</label>
      </li>
      </ul>
      <label for="tos" class="error">You must accept our terms of service</label>
      <p>
      <input type="submit"/>
      </p>
      </fieldset>
      
      

    现在,如果您在浏览器中刷新页面,并且尝试在没有完成必填字段或在表单中输入无效信息的情况下提交表单,您将在检测到问题时立即得到适当的错误消息。

    刚才发生了什么?

    我们使用验证插件向表单添加了一些简单的客户端验证。使用验证插件的最简单方法就是向表单元素添加一些类名和属性。验证插件会处理剩下的事情——它足够智能,能够识别 HTML5 输入类型并验证这些类型,并提供一些其他有用的验证规则,如必填字段、最大数字值、最小和最大长度以及信用卡号码。我们添加了一行 CSS 来样式化我们想要的错误消息。

    改善外观

    如果你尝试过用 CSS 样式化 Web 表单,那么你可能发现一些表单元素,如文本输入和按钮,非常容易样式化。有一些怪癖,但一旦你弄清楚了,你就可以让这些表单元素看起来几乎任何你想要的样子。然而,其他一些表单元素却更为顽固,对 CSS 样式几乎没有什么响应。设计一个可爱的表单,然后意识到从技术上讲它是不可能的,这实在令人沮丧。

    这些令人头痛的表单元素是:

    <select>
    <input type="file">
    <input type="checkbox">
    <input type="radio">
    
    

    不仅这四个表单元素在 CSS 中无法样式化,而且它们在不同浏览器和操作系统中的外观差异巨大,让我们对表单的外观几乎没有控制。让我们看看 Pixel Matrix 的 Uniform 插件如何帮助我们。

    行动时间 — 改善表单外观

    按照以下步骤利用 Uniform 插件实现可能的样式选项:

    1. 我们会从一个基本的 HTML 文件和相关文件和文件夹开始,就像我们在第一章中设置的那样,设计师,见到 jQuery。例如,在 HTML 文档的正文中,我们将建立一个简单的表单,其中包含每种难以样式化的表单元素的示例。从<form>标签开始:

      <form id="pretty-form" action="#">
      </form>
      
      
    2. 然后,在我们的表单中,我们将添加我们的表单元素。我们将从一个select下拉框开始:

      <fieldset>
      <legend>Select your favorite juice</legend>
      <p>
      <label for="juice">Favorite Juice</label>
      <select id="juice" name="juice">
      <option>Select one</option>
      <option value="orange">Orange Juice</option>
      <option value="grape">Grape Juice</option>
      <option value="grapefruit">Grapefruit Juice</option>
      <option value="cranberry">Cranberry Juice</option>
      <option value="tomato">Tomato Juice</option>
      <option value="pineapple">Pineapple Juice</option>
      <option value="apple">Apple Juice</option>
      </select>
      </p>
      </fieldset>
      
      

      我们遵循了与上一个表单相同的规则,确保表单正常工作并且易于访问。

      <select>的外观将取决于您的浏览器和操作系统,但在我这里,它在 Chrome 上的 Mac OSX 上的样子是这样的:

      行动时间 — 改善表单外观

    3. 接下来,我们将添加一个文件输入。

      <fieldset>
      <legend>Fruit Picture</legend>
      <p>
      <label for="fruit-photo">Upload a photo of your favorite fruit</label>
      <input type="file" id="fruit-photo" name="fruit-photo"/>
      </p>
      </fieldset>
      
      

      很难相信这个看似无害的标签竟然可能是如此头痛的样式来源,但事实就是如此。这是 Chrome 在 Mac OSX 上的样子:

      行动时间 — 改善表单外观

    4. 接下来,让我们添加一些复选框,如下所示:

      <fieldset>
      <legend>Which hot beverages do you enjoy?</legend>
      <ul>
      <li>
      <input type="checkbox" name="hot-bevs[]" id="hot-coffee">
      <label for="hot-coffee">Coffee</label>
      </li>
      <li>
      <input type="checkbox" name="hot-bevs[]" id="hot-chocolate">
      <label for="hot-chocolate">Hot Chocolate</label>
      </li>
      <li>
      <input type="checkbox" name="hot-bevs[]" id="hot-tea">
      <label for="hot-tea">Tea</label>
      </li>
      </ul>
      </fieldset>
      
      

      行动时间 — 改善表单外观

    5. 然后是一些单选按钮。

      <fieldset>
      <legend>Select your favorite soft drink</legend>
      <ul>
      <li>
      <input type="radio" name="soft-drinks" id="soda"/>
      <label for="soda">Soda</label>
      </li>
      <li>
      <input type="radio" name="soft-drinks" id="sparkling-water"/>
      <label for="sparkling-water">Sparkling water</label>
      </li>
      <li>
      <input type="radio" name="soft-drinks" id="iced-tea"/>
      <label for="iced-tea">Iced Tea</label>
      </li>
      <li>
      <input type="radio" name="soft-drinks" id="lemonade"/>
      <label for="lemonade">Lemonade</label>
      </li>
      </ul>
      </fieldset>
      
      

      行动时间 — 改善表单外观

    6. 我们将向表单中添加的最后一件事只是一些易于样式化的元素,以便我们学习如何将它们样式化以匹配我们的 Uniform 样式:

      <fieldset>
      <legend>Some other stuff about me</legend>
      <p>
      <label for="name">My name</label>
      <input type="text" id="name" name="name"/>
      </p>
      <p>
      <label for="about-me">About me</label>
      <textarea rows="10" cols="40" id="about-me" name="about-me"></textarea>
      </p>
      </fieldset>
      <p class="buttons">
      <input type="submit"/>
      <input type="reset"/>
      </p>
      
      

      执行动作的时间 — 改善表单外观

    刚才发生了什么?

    现在我们设置了未经样式处理的表单。我们的表单实际上看起来取决于您的浏览器和操作系统。我们按照本章前面建立的所有正确和可访问的表单设置规则进行设置。但是,这一次,我们包含了一些难以样式化的表单元素。现在让我们看看如何使用 Uniform 插件 —— 让我们的表单在尽可能多的浏览器中保持一致。

    样式化无法样式化的元素

    如果你想抽出一点时间尝试写一些 CSS 来样式化这些表单元素,你会发现它们几乎没什么影响。其中一些似乎根本不受 CSS 的影响,而当它们受到影响时,效果并不总是符合您的期望。难怪这些表单字段让每个人都头疼。JQuery 来拯救。

    时间来采取行动 —— 添加用于为无样式元素添加样式的 Uniform

    使用 Uniform 插件控制表单元素的样式,请按以下步骤操作:

    1. 让我们获取 Uniform 插件并看看它是如何工作的。前往 uniformjs.com/ 并点击大的下载 Uniform按钮。执行动作的时间 — 添加用于为无样式元素添加样式的 Uniform

    2. 解压文件夹并查看其中的内容。执行动作的时间 — 添加用于为无样式元素添加样式的 Uniform

      • 这很简单,对吧?一些样式,一个演示,一些图片,以及两个版本的 Uniform 插件 —— 一个压缩和一个未压缩。我们以前见过这个。

        默认情况下,Uniform 自带一个默认样式表和图片。但是,还有其他样式可用。回到 uniformjs.com,如果在导航中点击主题,您将看到当前可用的主题。我非常喜欢 Aristo 的外观,所以我要下载它。

      执行动作的时间 — 添加用于为无样式元素添加样式的 Uniform

      • 这给我一个简单的 ZIP 文件,里面只有一些 css 和图片:

      执行动作的时间 — 添加用于为无样式元素添加样式的 Uniform

    3. 接下来,我们需要将这些文件放入我们自己的项目中,并附加到我们的 HTML 页面中。让我们从 JavaScript 开始。将 jquery.uniform.min.js 复制到您自己的 scripts 文件夹中,并将 Uniform 脚本在 jQuery 和您自己的 scripts.js 文件之间引用:

      <script src="img/jquery.js"></script>
      <script src="img/jquery.uniform.min.js"></script>
      <script src="img/scripts.js"></script>
      </body>
      
      
    4. 现在将您想要使用的主题的 CSS 文件复制到您自己的 styles 文件夹中,并在文档的头部引用它:

      <head>
      <title>Chapter 12: Improving Forms</title>
      <link rel="stylesheet" href="styles/uniform.aristo.css"/>
      <link rel="stylesheet" href="styles/styles.css"/>
      
      
    5. 我们需要获取的最后一样东西是关联的图片。将您选择的主题的图像文件夹的内容复制到您自己的 images 文件夹中。现在,您自己项目的结构应该看起来类似于以下截图:执行动作的时间 — 添加用于为无样式元素添加样式的 Uniform

    6. 现在,我们可以调用 uniform() 方法来为我们的无法样式化的表单元素添加样式了。打开您的 scripts.js 文件,并插入一个文档就绪语句:

      $(document).ready(function(){
      //our code will go here
      });
      
      
    7. Uniform 允许我们选择我们想要样式化的表单元素。在这种情况下,我们想要样式化所有四个顽固的元素,所以我们的选择器将是:

      $(document).ready(function(){
      $('select, input:checkbox, input:radio, input:file');
      });
      
      
    8. 然后,剩下的就是调用 uniform() 方法:

      $(document).ready(function(){
      $('select, input:checkbox, input:radio, input:file').uniform();
      });
      
      

      现在,如果您在浏览器中刷新页面,您将看到这些顽固且不可样式化的表单元素现在与您选择的 Uniform 主题相匹配。

      行动时间 — 为不可样式化的元素添加统一样式

    • 仍然有一些奇怪的 CSS 问题需要处理,我们的 fieldsets、legends、按钮和文本输入框不匹配。让我们写一点 CSS 将它们整合在一起。

    所有样式

    我们还有一些 CSS 问题需要解决 — 我们的复选框和单选按钮列表仍然有它们的项目符号,我们的文本输入、按钮、fieldsets 等仍未经过样式化。让我们将所有东西都样式化,以匹配我们选择的 Uniform 主题。

    行动时间 — 为可样式化元素添加样式

    1. 打开您的 styles.css 文件。我们将从样式化 fieldsets 和 legends 开始:

      fieldset {
      background: #fff;
      border: 1px dotted #83b0ca;
      margin: 10px 20px 0 20px;
      padding:10px;
      }
      legend {
      background: #bed6e3;
      border:1px solid #8fb7cf;
      color: #1C4257;
      padding: 0 5px;
      box-shadow:2px 2px 2px rgba(0,0,0,0.2);
      }
      
      

      我选择了与我选用的 Aristo 主题相匹配的蓝色。如果您选择了不同的主题,请随意使用不同的颜色和样式来匹配您选择的主题。

    2. 接下来,我们将为表单中使用的某些容器元素添加样式:

      fieldset p {
      margin: 0 0 10px 0;
      }
      fieldset ul {
      list-style: none;
      margin: 0;
      padding: 0;
      }
      label {
      display: block;
      }
      ul label {
      display: inline;
      width: auto;
      }
      p.buttons {
      margin: 20px;
      }
      
      
    3. 接下来,我们将为文本输入和文本区域添加一些样式,以匹配我们的 Aristo 表单元素:

      input[type="text"],
      textarea {
      border: 1px solid #ccc;
      border-radius: 3px;
      box-shadow: inset 0 0 4px rgba(0,0,0,0.3);
      moz-border-radius: 3px;
      moz-box-shadow: inset 0 0 4px rgba(0,0,0,0.3);
      padding: 4px;
      webkit-border-radius: 3px;
      webkit-box-shadow: inset 0 0 4px rgba(0,0,0,0.3);
      width: 250px;
      }
      
      
    4. 最后,但同样重要的是,我们将样式化我们的按钮。Aristo 主题使用了一个漂亮的蓝色渐变,所以我将为我的按钮使用渐变。我将不得不为支持所有浏览器编写相当多的代码,但这是它:

      input[type='submit'],
      input[type='reset'] {
      background: rgb(185,224,245);
      background: linear-gradient(top, rgba(185,224,245,1) 0%,rgba(131,176,202,1) 100%);
      background: -moz-linear-gradient(top, rgba(185,224,245,1) 0%, rgba(131,176,202,1) 100%);
      background: -ms-linear-gradient(top, rgba(185,224,245,1) 0%,rgba(131,176,202,1) 100%);
      background: -o-linear-gradient(top, rgba(185,224,245,1) 0%,rgba(131,176,202,1) 100%);
      background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(185,224,245,1)), color-stop(100%,rgba(131,176,202,1)));
      background: -webkit-linear-gradient(top, rgba(185,224,245,1) 0%,rgba(131,176,202,1) 100%);
      border: solid 1px #6e93b0;
      border-radius: 2px;
      box-shadow: rgba(0,0,0,0.15) 0px 1px 3px;
      color: #1C4257;
      cursor: pointer;
      display: inline-block;
      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b9e0f5', endColorstr='#83b0ca',GradientType=0 );
      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eef3f8', endColorstr='#96b9d4',GradientType=0 );
      font-size: 1em;
      font-weight: bold;
      height: 27px;
      line-height: 26px;
      margin-right: 5px;
      moz-border-radius: 2px;
      moz-box-shadow: rgba(0,0,0,0.15) 0px 1px 3px;
      padding: 0 10px;
      text-shadow: rgba(255,255,255,0.5) 0px 1px 0px;
      webkit-border-radius: 2px;
      webkit-box-shadow: rgba(0,0,0,0.15) 0px 1px 3px;
      }
      input[type='submit']:hover,
      input[type='reset']:hover {
      color: #0b1b24;
      }
      input[type='submit']:active,
      input[type='reset']:active {
      background: rgb(131,176,202);
      background: linear-gradient(top, rgba(131,176,202,1) 0%,rgba(185,224,245,1) 100%);
      background: -moz-linear-gradient(top, rgba(131,176,202,1) 0%, rgba(185,224,245,1) 100%);
      background: -ms-linear-gradient(top, rgba(131,176,202,1) 0%,rgba(185,224,245,1) 100%);
      background: -o-linear-gradient(top, rgba(131,176,202,1) 0%,rgba(185,224,245,1) 100%);
      background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(131,176,202,1)), color-stop(100%,rgba(185,224,245,1)));
      background: -webkit-linear-gradient(top, rgba(131,176,202,1) 0%,rgba(185,224,245,1) 100%);
      filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#83b0ca', endColorstr='#b9e0f5',GradientType=0 );
      }
      
      

      我在鼠标悬停时添加了微妙的文字颜色变化,并在点击按钮时反转了渐变。现在,刷新浏览器中的页面,看看我们美丽的表单。

      行动时间 — 为可样式化元素添加样式

    刚才发生了什么?

    我们使用了 Pixelmatrix 的 Uniform jQuery 插件来样式化以前顽固且无法样式化的表单元素。我们选择了一个预设主题,并将所有相关的 CSS 和图像附加到我们的页面上,然后选择我们想要样式化的每一种表单元素,并调用 uniform() 方法。然后,我们使用我们的 CSS 技能来样式化其他表单元素,如简单的文本输入、文本区域和一些按钮,以匹配我们选择的主题。结果是一个漂亮的表单,在不同的浏览器中看起来一致,并且对于禁用 JavaScript 的用户仍然完美地工作。

    我们自己的主题

    当然,这个 Aristo 主题很不错,但是如果它不匹配我们的网站怎么办?我们还有其他选择吗?当然有!如果预设的主题都不符合您的网站,您可以使用自己的样式和颜色制作自己的主题,以匹配您喜欢的任何网站。事实上,Pixelmatrix 已经使这变得超级简单了。以下是您可以做到的:

    行动时间 — 创建自定义的统一主题

    1. 首先从 Pixelmatrix 下载主题工具包。你可以在 uniformjs.com 的主题部分找到它!行动时间 — 创建自定义 Uniform 主题

    2. 解压缩文件夹,里面有两个 PSD 文件 — sprite.psdsprites.psd。在 Photoshop 中打开 sprite.psd 并按照您的喜好为表单元素添加样式。如果您想要更大或更小的表单元素,您可以更改元素的大小。Sprites.psd 仅用于说明每种样式的用途。您可以将其用作参考,以确保覆盖所有可能性,但实际上您不需要使用它来创建您的主题。

    3. 当你的精灵准备好时,转到 uniformjs.com/themer.html行动时间 — 创建自定义 Uniform 主题

      • 填写表单,包括选择精灵的高度、复选框和单选按钮的宽度和高度,以及文件输入的高度。然后点击生成代码。生成用于使 Uniform 与你的精灵配合工作所需的 CSS 将为您生成。将其复制粘贴到 CSS 文件中并保存到您的项目中。
    4. 将你的新 CSS 文件附加到 HTML 文档中,并将你的精灵保存为 PNG 文件,保存到你项目的images文件夹中,然后你应该一切就绪了。你可能会发现一些需要进行微小调整的地方,但设置一个自定义 Uniform 主题就是这么简单。

    注意

    如果您想将您的主题贡献给 Uniform 社区,让其他设计师和开发人员使用,您可以通过将您的主题的 zip 文件发送到 <josh@pixelmatrixdesign.com> 来将其提交给 Pixelmatrix。

    刚刚发生了什么?

    我们学习了如何使用 Pixelmatrix 提供的主题工具包和自定义主题 CSS 生成器,快速轻松地创建我们自己的 Uniform 主题。

    概要

    嗯,这就结束了有关表单的章节。我们学会了如何正确使用新的 HTML5 表单元素来创建一个功能完美且易于访问的表单。我们学会了如何将焦点放在表单中的第一个字段上,在所有浏览器中使用占位文本,验证我们网站访客的表单输入,并为那些难以样式化的固执和臭名昭著的表单元素添加样式。现在你拥有了一系列工具来创建在你的网站上增强你的网站访客体验的美观表单。最重要的是,它们都能够在禁用 JavaScript 的用户上优雅地降级,因为我们采用了渐进增强的思维方式来处理我们的表单 —— 首先构建一个可工作的表单,然后逐步添加增强功能,以供那些浏览器支持的网站访客使用。

    我知道对于设计师来说,JavaScript 可能是一个可怕的主题。感谢你一直陪伴我到书的最后!我希望现在你对 jQuery 有了基本的理解,并且确信自己能够自信地应对下一个 JavaScript 挑战。你知道如何有效地利用 jQuery 库来增强你的网站。你知道如何找到好的插件,快速轻松地编写交互功能。你知道 CSS 和 JavaScript 如何共同工作,以增强网站访客在你的网站上的体验。你也知道,如果遇到困难,网络上有很多教程、资源、帮助论坛、文章和讨论可以帮助你。

    对于 jQuery 而言,每一次发布都会变得更加出色 — 更加简洁、更快、更有能力。jQuery 团队会注意保持文档的更新,因此你总能弄清楚如何使用每个方法。jQuery 团队聪明而迅速,新的 jQuery 更新定期发布。所有这些都指向一个活跃且有用的库,在 Web 上的受欢迎程度将继续增长。它是许多程序员的最爱,从经验丰富的黑客到像你这样的初学者。

    希望你喜欢这本书,并且它给你带来了许多新的想法,可以为你的网站设计和构建交互式元素。一定要与 jQuery 社区保持联系 —— 这将是你在进一步改进和发展 JavaScript 技能方面的最佳资源。

posted @ 2024-05-19 20:13  绝不原创的飞龙  阅读(8)  评论(0编辑  收藏  举报