JavaScript学习笔记--05

案例研究:JavaScript美术馆

前面学习了DOM的一些知识,今天来试着运用前面所学,完成一个案例:用JavaScript和DOM去建立一个图片库,并称之为“JavaScript美术馆”。
步骤:
  1. 编写一份优秀的标记语言文档;
  2. 编写一个JavaScript函数以显示用户想要查看的图片;
  3. 在标记语言文档里触发一个调用JavaScript图片显示的函数;
  4. 对这个JavaScript函数功能进行扩展。这需要用到几个新的DOM方法。

编写标记语言文档:为这些图片创建一个链接清单。

html文档如下:
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Image Gallery</title>
</head>
<body>
<h1>Snapshots</h1>
<ul>
    <li>
        <a href="images/巴西野牡丹.jpg" title="baxiyebaihe">巴西野百合</a>
    </li>
    <li>
        <a href="images/白玫瑰.jpg"  title="baimeigui">白玫瑰</a>
    </li>
    <li>
        <a href="images/白玫瑰裙.jpg"  title="baimeiguiqun">白玫瑰裙</a>
    </li>
    <li>
        <a href="images/sunflower.jpg"  title="xiangrikui">向日葵</a>
    </li>
</ul>

</body>
</html>

把这份文档保存为gallery1.0.html文件,并把图片集中保存在子目录images里。
得到页面:



这是一个令人满意的网页,但是他的默认行为还不太理想。下面需要做几点改进:
  • 当点击某个链接时,希望能停留在这个网页而不是转到另一个窗口。
  • 当点击某个链接时,希望能再这个网页同时看到那张图片以及原有的图片清单。
为了实现上面的希望,要完成几项改进:
  • 通过添加一个“占位符”图片的方法在这个主页上为图片预留一个浏览区域。
  • 在点击某个链接时,将拦截这个网页的默认行为。
  • 在点击某个链接时,将“占位符”图片替换为与那个链接相对应的图片。
首先,解决“占位符”图片问题:
将下面这些代码插入到图片名单的末尾
<img id="placeholder" src="images/placeholder.jpg" alt="my imag gallery"/>
对这个图片的id属性进行了设置,以便可以通过外部样式表来对图片的显示位置和显示效果加以控制。
下面是页面加了“占位符”图片后的显示效果:

接下来,是编写一些必要的JavaScript代码。

编写JavaScript函数

为了把“占位符”图片替换为想要查看的图片,需要改变它的src属性。setAttribute()方法是完成这项工作的最佳选择。可以利用这个方法编写一个函数。那个函数只有一个参数,也就是想查看的那张图片的链接;它将通过改变“占位符”图片的src属性的办法将其替换为想看的那张图片。
1.函数命名为showPic,函数的参数命名为whichpic:function showPic(whichpic)
whichpic代表着一个元素节点,具体地说,那将是一个指向某个图片的<a>元素。要知道那个图片的文件路径,这个路径可以通过在whichpic元素上调用getAttribute()方法查出来——只要把“href”作为参数传递给getAttribute()方法,就可以知道那个图片的文件路径:
whichpic.getAttribute("href")
给这个路径存入一个变量以便在后面的语句中使用它。
var source=whichpic.getAttribute("href");
2.将“占位符”图片检索出来,可以使用getElementById():
var placeholder=document.getElementById("placeholder");
3.使用setAttribure()方法对placeholder元素的src属性进行刷新。
placeholder.setAttribute("src",source);

PS:DOM是一种是适用于多种环境和多种程序设计语言的通用型API。

showPic函数的代码清单:
function showPic(whichpic){
    var source=whichpic.getAttribute("href");
    var placeholder=document.getElementById("placeholder");
    placeholder.setAttribute("src",source);
}

接下来的任务是把这个JavaScript函数与HTML文档结合起来。

JavaScript函数的调用

将showPic.js保存在scripts文件夹里。在html文档的<head>标签之后添加:
<script type="text/javascript" src="scripts/showPic.js"></script>

有了上面这条语句,把showPic函数与图片库HTML文档结合起来的任务就已经完成了一半——还需要为HTML文档里的每个图片链接添加一个函数调用动作,否则showPic函数将永远也不会被调用。将通过添加一个事件处理函数(event handler)的办法来完成。

事件处理函数

事件处理函数的作用是,在预定事件发生时让预先安排好的JavaScript代码开始执行,用术语来说就是“触发一个动作”。例如,如果想在鼠标指针悬停在某个元素上时触发一个动作,就需要使用onmouseover事件处理函数;如果想在鼠标指针离开某个元素的时候出发一个动作,就需要使用onmouseout事件处理函数。在“JavaScript美术馆”案例里,希望用户在点击某个链接时触发一个动作,所以需要使用onclick事件处理函数。
onclick事件处理函数去触发的动作是调用showPic函数,而想调用这个函数,就必须要向它传递一个参数:一个带有href属性的元素节点。在图片库HTML文档里,当把onclick事件处理函数嵌入一些链接时,需要把那些链接本身用作showPic函数的参数。
 
有个非常简单但又非常有效的方法可以做到这一点:使用JavaScript语言中的 this关键字。这个关键字的含义是“这个对象”。具体到正在讨论的这个例子,将使用this关键字来表示“这个<a>元素节点”:
showPic(this)
综上所述,将使用onclick事件处理函数去调用showPic(this)方法。还用事件处理函数调用JavaScript代码的语法如下图所示:
event="JavaScript statement(s)"
要注意的是,在上面的语法里,JavaScript代码是包含在一对引号之间的:可以把任意数量的JavaScript语句放在这对引号之间,只要把各条语句用分号间隔开即可。
下面这条语句将完成“使用onclick事件处理函数调用showPic(this)方法”的任务:
οnclick="showPic(this);"
不过,如果只是将上面的事件处理函数插入到HTML文档中的链接里去的话,将遇到遮掩给一个问题:在onclick事件发生时,不仅showPic(this)函数被调用,链接被点时的默认行为也将发生。这样用户会被带到另一个图片查看窗口里去,这不是我们所希望的,应该要阻止这种默认行为。
要实现这一目的,必须对事件处理函数的工作机制有进一步的了解: 在给某个元素添加了事件处理函数后,一旦发生预定事件,相应的JavaScript代码就会得到执行;那些JavaScript代码可以返回一个结果,而这个结果将被传递回那个事件处理函数。例如,可以给某个链接添加一个onclick事件处理函数,并让这个处理函数所触发的JavaScript代码返回布尔值true或者false。这样一来,当这个链接被点击时,如果那段JavaScript代码返回给onclick事件处理函数的值是true,onclick事件处理函数将认为“这个链接被点击了”;反之,如果那段JavaScript代码返回给onclick事件处理函数的值是false,onclick事件处理函数将认为“这个链接没有被点击”。
所以在onclick事件处理函数所触发的JavaScript代码里增加一条return false语句,就可以不让用户被他们所点击的链接带到另外一个图片查看窗口里去:
οnclick="showPic(this); return false;"
接下里,只要把这个onclick事件处理函数添加到每个链接上去即可。这有点麻烦,后面会介绍如何避免这种麻烦。
下面是图片库HTML文档在我以手动方式把这个onclick事件处理函数添加到各个有关链接后的样子:

对JavaScript函数进行扩展

图片库HTML文档里的每个图片链接都有一个title属性。可以把这属性的值提取出来并让他们伴随相应图片一同显示在网页上。title属性的值可以用getAttribute()方法轻而易举地提取出来。把下面的语句添加到showPic()函数的开头,就可以把title属性的值保存到一个变量里:
var titletext=whichPic.getAttribute("title");
解决了提取title属性值的问题,还需要把它插入到HTML文档中的适当位置。

下面学习几个新的DOM属性。
childNodes属性从给定的文档的节点树里把任何一个元素的所有子元素检索出来
childNodes属性将返回一个 数组,这个数组包含给定元素节点的全体子元素:element.childNodes
假设要把某个文档的body元素的全体子元素检索出来。首先,得用getElementByTagName()方法来得到body元素。因为每个文档只有一个body元素,所以getElementByTagName("body")方法所返回的数组中的第一个(也就是唯一一个)元素:
<pre name="code" class="html">var body_element=document.getElements<span style="font-family: Arial, Helvetica, sans-serif;">ByTagName("body")[0];</span>
 接下来,可以用下面的语法把body的全体子元素检索出来: 
body_element.childNodes
顺便说一句,body元素还有一个更简单的专用记号:document.body
因为childNodes属性将返回一个数组,所以可以用数组数据类型的length属性查出它所包含的元素的个数:
body_element.childNodes.length
可以把下面这个小函数添加到showPic.js文件里:
<pre name="code" class="html">function countBodyChildren(){
var body_element=document.getElementsByTagName("body")[0];
alert(body_element.childNodes.length)
}

 
要让这个函数在页面加载是被执行,就需要使用onload事件处理函数。将下面的语句加到代码段的末尾:
window.οnlοad=countBodyChildren;
这条语句将在页面加载是调用countBodyChildren函数。

nodeType属性:可以知道正在与哪种节点打交道(节点包括:元素节点(属性值为1),属性节点(属性值为2),文本节点(属性值为3)
nodeType属性返回的是一个数字而不是英文字符串。
下面是nodeType属性的调用方法:node.nodeType
在HTML文档里添加一段描述性文本
为了让“JavaScript美术馆”变得与众不同,可以给它添加一个文本节点。在显示图片时把这个文本节点的值替换为一个来自某个属性节点(某个图片链接的title属性的值)的值。
首先,在<imag>标签之后添加一段代码:
<p id="description">Choose an image.</p>
用JavaScript代码改变<p>元素的文本内容
需要修改showPic()函数
function showPic(whichpic){
    var source=whicpic.getAttribute("href");
    var placeholder=document.getElementById("placeholder");
    placeholder.setAttribute("src",source);
    <strong>var text=whichpic.getAttribute("title");
    var description=document.getElementById("description");</strong>
}
下一个任务是实现文本的切换显示效果
nodeValue属性:改变某个文本节点的值,检索(和设置)节点的值
语法:node.nodeValue
firstChild和lastChild属性
数组元素childNodes[0]有个更直观易读的同义词—— firstChild,这个记号本身是一个属性:node.firstChild这个用法与node.childNodes[0]完全等效。
childNodes[]数组的最后一个元素node.childNodes[node.childNodes.length-1]与node.lastChild属性的用法也完全一致。
PS:nodeValue属性的用途并非限于此。不仅可以用它来检索某个节点的值,还可以用它来设置某个节点的值;后一种用法正是目前需要的。
修改showPic()函数
function showPic(whichpic){
    var source=whichpic.getAttribute("href");
    var placeholder=document.getElementById("placeholder");
    placeholder.setAttribute("src",source);
    <strong>var text=whichpic.getAttribute("title");
    var description=document.getElementById("description");
    description.firstChild.nodeValue=text;</strong>
这样子就实现了我们最初的希望。
如果想让这个“JavaScript美术馆”变得更加美观,可以给它添加样式表:
body{
    font-family: "Helvetica","Arial",san-serif;
    color:#333;
    background-color: azure;
    margin: 1em 10%;
}
h1{
    color:#333;
    background-color: transparent;
}
a{
    color:#c60;
    background-color: transparent;
    font-weight: bold;
    text-decoration: none;
}
ul{
    padding:0;
}
li{
    float:left;
    padding: 1em;
    list-style: none;
}
这样基本就实现了“JavaScript美术馆”。
但是在我的实际编程中,我遇到了一个问题:使用了样式表之后,图片变成在列表的右边,而不是理想中的在列表的下面:

分析原因,可知,这可能与CSS中的浮动有关。暂时我还未找出解决思路,留待后面补充。

20160714补充:
今天突然翻看到之前留的问题,想到一个最简单的解决方案:在HTML文档中加入3个换行符。添加后,效果如下:


这样初步实现了理想中的效果。后面会慢慢学习,并对其加以修正!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值