7.3.2 编程
这个教程扩展了前一个教程,但是,开始的Web页面稍微重新组织了一下:缩略图现在在左边一列,而ID为photo的一个<div>标签添加到了页面上(如图7-4所示)。
注意:参见1.3节中的“注意”部分以获取有关如何下载教程文件的信息。
1.在文本编辑器中打开chapter07目录下的文件gallery.html。
这个文件包含了前一个教程的程序,添加了一个新的<div>标签,用来显示每个缩略图的较大版本。既然显示照片集图像的过程是通过单击包含了缩略图的一个链接而触发的,那么第一步就是创建这些链接的一个选择并为每个链接添加click事件。
2.找到JavaScript注释“insert new programming below this line”,并且添加如下的代码:
$('#gallery a').click(function(evt){
});//end click
选择器#gallery a选择了ID为gallery的另一个标签中的所有链接标签。.click是添加事件处理程序的一个jQuery函数(如果需要复习一下关于事件的知识,参见5.2节)。此外,这段代码把一个匿名函数传递给了click事件(5.4.3节介绍过,作为对事件的响应而执行的函数,自动地有一个事件对象传递给它)。
在这个例子中,变量evt存储了事件对象。我们将在下面的步骤中使用它来阻止浏览器打开单击的链接。
3.在步骤2中添加的两行代码之间输入evt.preventDefault();。
通常,单击一个链接会使得We b浏览器载入链接所指向的内容(We b页面、图像文件、PDF文档等)。在这个例子中,这个链接仍然存在,以便不支持JavaScript的访问者仍然能够访问缩略图的较大版本。为了防止对于那些支持JavaScript的访问者来说Web浏览器打开该链接,运行事件对象的preventDefault()函数(参见5.4.4节的介绍)。
接下来,我们将获取该链接的href属性。
4.按下回车键创建一个新的空白行,并且输入如下粗体所示的代码:
$('#gallery a').click(function(evt){
evt.preventDefault();
var imgPath=$(this).attr('href');
});//end click
这里的$(this)指向了单击的元素,换句话说,是一个链接。链接的href属性指向了链接所去向的页面或资源。在这个例子中,每个链接包含了较大图像的一个路径。这是重要的信息,因为可以使用它来添加指向图像文件的一个图像标签。但是,在这么做之前,需要得到当前显示在页面上的较大图像的一个引用。毕竟,我们需要知道它是什么,以便能够将其淡出视线。
提示:你将会看到步骤4中的click()事件中的每行代码都缩进了。这是可选的,但是它有助于使代码更容易阅读,如5.4.2节中的“常见问题:JavaScript中的空格、制表符和回车”部分所述。很多程序员对于每一级缩进使用两个空格(或者一个制表符)。
5.按下回车键并输入var oldImage=$('#photo img');。
变量oldImage包含了一个jQuery选择,其中包含了photo<div>中的<img>标签(如图7-4所示)。现在,应该为新图像创建一个标签了。
6.再次按下回车键,并且向脚本中添加var newImage=$('<img src="’+imgPath+’">');。
这里进行的事情很少。jQuery允许选择页面的HTML中的一个元素。例如,$('img')选择了页面上的所有图像。此外,jQuery对象可以为页面添加一个新的元素。例如,$('<p>Hello')创建了包含单词Hello的一个新的段落标签。这行创建了一个新的<img>标签,并且将其存储在名为newImage的一个变量中。
既然jQuery对象期待一个字符串作为参数(例如’<p>Hello</p>'),这行代码连接或组合几个字符串得到一个字符串。第一个字符串(由单引号包围着)是<img src=";第二个字符串存储在变量imgPath中(在步骤4中创建),并且是到图像文件的路径(例如../_images/large/slide1.jpg);第三个字符串(也用单引号包围着)是">。组合到一起,它们构成了一个HTML标签:<img src="../_images/large/slide1.jpg">。当脚本把该字符串传递给jQuery对象,例如$('<img src="../_images/large/slide2.jpg">'),浏览器就创建了一个页面元素。它没有在页面上显示,但是浏览器准备好随时将其添加到页面上。
7.添加下面第6行到第8行的代码,于是,目前为止所添加的代码如下所示:
1$('#gallery a').click(function(evt){
2
evt.preventDefault();3
var imgPath=$(this).attr('href');
4
var oldImage=$('#photo img');5
var newImage=$('<img src="’+imgPath+’">');
6
newImage.hide();7
$('#photo').prepend(newImage);
8
newImage.fadeIn(1000);
9});//end click
在第6行中,新创建的图像(存储在变量newImage中)使用6.1.2节介绍的hide()函数隐藏。这个步骤是必需的,意味着如果只是添加了在第5行创建的图像标签,图像将会立即在页面上可见,而没有漂亮的淡入效果。因此,首先隐藏图像,然后将其添加到页面的photo<div>中(第7行)。prepend()函数(参见4.7节)把HTML添加到一个标签中。特别是,它把HTML添加到标签的开头。此时,页面上的photo<div>内有两幅图像,图7-5展示了一幅图像如何位于另一幅图像之上。上面的图像是不可见的,但是在第8行,fadeIn()函数使得图像在1000毫秒(1秒)的过程内慢慢淡入。
现在该让最初的图像淡出了。
图 7-5 要实现这样的效果:两幅照片出现在页面上的同一位置,但是,一幅照片淡入而另一幅照片淡出,我们需要使用一些创造性的CSS。绝对定位允许一个元素位于页面之上,甚至是在另一个元素之上。在这个例子中,两幅图像都是在<d i v>标签内部绝对定位的,这使得它们中的一个浮动在另一个之上。在chapter07文件夹中的gallery.html文件的<head>中所潜入的样式表,拥有所需的所有CSS,确保检查#photo img样式。此外,包含图像的标签需要一个相对定位,以便让图像相对于页面上的该位置来定位
8.按下回车键,并且添加如下所示的3行代码:
oldImage.fadeOut(1000,function(){
$(this).remove();
});//end fadeout
在步骤5中,我们创建了一个名为oldImage的变量,并且把页面上最初图像的一个引用存储在其中。这就是想要淡出的图像,因此,使用fadeOut()函数。我们给该函数传递了两个参数:第一个参数是效果的持续过程,为1000毫秒(1秒);第二个参数是一个回调函数(参见6.4节)。这个回调函数在淡出效果完成后运行,并且移除该图像的<img>标签。
注意:remove()函数将在13.4节中介绍。它实际上从DOM移除了标签,这会从浏览器的内存擦除HTML,释放计算机资源。如果没有采取这一步骤,每次访问者单击缩略图,都会添加一个新的<img>标签(参见步骤7),旧的图像直接隐藏,而没有删除。我们最终会得到很多隐藏的<img>标签,但它们仍然嵌入在Web页面中,这大大降低了Web浏览器的响应速度。
还剩下最后一步,载入第一幅图像。图像应该放入其中的<div>标签当前为空。我们可以在该位置输入一个<img>标签,这样,当页面载入的时候,针对第一个缩略图,将会有一幅较大的图像。但是,为什么这么麻烦呢?我们已经可以使用JavaScript了。
9.在click()函数的末尾(下面的第13行)添加最后一行代码。完成后的程序如下所示:
1$('#gallery a').click(function(evt){
2 evt.preventDefault();
3 var imgPath=$(this).attr('href');
4 var oldImage=$('#photo img');
5 var newImage=$('<img src="’+imgPath+’">');
6 newImage.hide();
7$('#photo').prepend(newImage);
8 newImage.fadeIn(1000);
9 oldImage.fadeOut(1000,function(){
10$(this).remove();
11});//end fadeout
12});//end click
13$('#gallery a:frst').click();
最后一条语句有两部分。第一部分是选择器:#gallery a:first,选择位于gallery<div>中的第一个链接。第二部分是click()函数。到目前为止,我们已经使用了jQuery的click()分配了当事件发生时运行的一个函数。然而,如果没有给事件函数传递任何参数,jQuery只是触发事件,引起任何之前定义的事件处理程序运行。因此。这一行代码在第一个链接上触发了一次单击,使得Web浏览器运行我们在前面第1行到第11行所创建的函数。这就使得在页面载入后,第一个缩略图的较大图像淡入视线。
保存页面并且在Web浏览器中预览。当鼠标光标移动到缩略图上的时候,它不仅改变了颜色,单击一个缩略图还会使得相关的较大图像淡入视线(如果代码遇到麻烦,文件complete_gallery.html包含了这段脚本的一个可工作的副本)。