JavaScript美术馆进化史

内容选自<<JavaScript DOM 编程艺术>>第4-6章,跟着作者一起见证美术馆的进化吧.

先放效果图,然后一步步做出每个效果.每个效果都有它实用的地方,且知道过程可以更好的理解代码为什么这么写,这就是 我写这篇博文的原因.

v1

v1实用的默认版本,没有实用js和css,完全是纯html.代码如下

 1     <!DOCTYPE html>
 2     <html lang="en">
 3         <head>
 4             <meta content="text/html; charset=utf-8" http-equiv="content-type"></meta>
 5             <title>
 6
 7                 Image Gallery
 8
 9             </title>
10         </head>
11         <body>
12             <h1>
13
14                 Snapshots
15
16             </h1>
17             <ul>
18                 <li>
19                     <a title="A fireworks display" href="images/fireworks.jpg">
20
21                         Fireworks
22
23                     </a>
24                 </li>
25                 <li>
26                     <a title="A cup of black coffee" href="images/coffee.jpg">
27
28                         Coffee
29
30                     </a>
31                 </li>
32                 <li>
33                     <a title="A red, red rose" href="images/rose.jpg">
34
35                         Rose
36
37                     </a>
38                 </li>
39                 <li>
40                     <a title="The famous clock" href="images/bigben.jpg">
41
42                         Big Ben
43
44                     </a>
45                 </li>
46             </ul>
47         </body>
48     </html>

点击每个链接后,将会在本页面打开一个只有该图片的新页面.浏览器地址改变,进入到该图片路径.------这是浏览器默认形式.

缺点:1.无序列表前面的黑点难看;

2.用户点击链接后前进到图片页,如果要看其他图片却必须点后退.

v2

v2版本解决了v1的第2个问题,让用户可以在不离开当前页面的情况下切换看图片.代码如下

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta http-equiv="content-type" content="text/html; charset=utf-8" />
 5   <title>Image Gallery</title>
 6     <script type="text/javascript" src="scripts/showPic.js"></script>
 7 </head>
 8 <body>
 9   <h1>Snapshots</h1>
10   <ul>
11     <li>
12       <a href="images/fireworks.jpg" title ="A fireworks display" onclick="showPic(this); return false;">Fireworks</a>
13     </li>
14     <li>
15       <a href="images/coffee.jpg" title="A cup of black coffee" onclick="showPic(this); return false;">Coffee</a>
16     </li>
17     <li>
18       <a href="images/rose.jpg" title="A red, red rose" onclick="showPic(this); return false;">Rose</a>
19     </li>
20     <li>
21       <a href="images/bigben.jpg" title="The famous clock" onclick="showPic(this); return false;">Big Ben</a>
22     </li>
23   </ul>
24   <img id="placeholder" src="images/placeholder.gif" alt="my image gallery" />
25 </body>
26 </html>

function showPic(whichpic) {
  var source = whichpic.getAttribute("href");
  var placeholder = document.getElementById("placeholder");
  placeholder.setAttribute("src",source);
}

(1)为了在当前页面显示图片,作者挑选了一张图片作图片占位符.代码即<img 那行

(2)我们可以实现改变占位符图片的url来切换图片.具体来说就是改变img的src属性;这时我们想到setAttribute()方法.setAttribute(原属性,新属性) 用新属性替换原属性;

新属性应该是各链接地址,原属性是img的src. 因为我们要用各链接的地址来替换img的src嘛.这样img那个地方出现的就是各链接链接到的内容.

(3)难点来了.如果只做一二步,你会发现跟以前那个没撒区别,图片占位符完全是个摆设.那么怎么让链接跟图片占位符建立某种联系呢.我们想到了html的事件处理函数.

HTML 4 的新特性之一是可以使 HTML 事件触发浏览器中的行为,比方说当用户点击某个 HTML 元素时启动一段 JavaScript。详情百度w3c.

为此我们在每个<a>里加上 onclick="showPic(this); return false;"  鼠标点击时触发showPic函数,该函数把当前<a>当作参数,然后进行showPic的操作.但是这个a我们要用他就必须定个Id,不然容易跟页面里的其他a打混,用this指代当前对象.return flase取消浏览器默认行为.如果改为true的话js和浏览器默认这两个事件都会发生.根据代码顺序先在页面显示然后以极快的速度跳转到新的页面.(这或许就是我以前看到的某些网站的弊端吧)

v3

v3是在v2的基础上加上了一段描述性文本,文本会随着图片的选择而发生改变.但问题是文本节点没有src或者href属性啊.

我们知道文本一般是存在于某个标签内,这里是p.

nodeValue的作用是检索和改变某个节点的值(注意与setAtrribute的区别).此外注意我们改变的文本节点的值而不是p.

这里我们用从各个链接那得来的值(存在text变量里)来改变Id是description的p标签内的文本内容.

 var text = whichpic.getAttribute("title");
  var description = document.getElementById("description");
  description.firstChild.nodeValue = text;

v4

v3已经将要实现的功能实现了,v4算是美化页面.下面是css代码

 1 body {
 2   font-family: Helvetica,Arial,serif;
 3   color: #333;
 4   background-color: #ccc;
 5   margin: 1em 10%;
 6 }
 7 h1 {
 8   color: #333;
 9   background-color: transparent;
10 }
11 a {
12   color: #c60;
13   background-color: transparent;
14   font-weight: bold;
15   text-decoration: none;
16 }
17 ul {
18   padding: 0;
19 }
20 li {
21   float: left;
22   padding: 1em;
23   list-style: none;
24 }
25 img {
26   display:block;
27   clear: both;
28 }

注意(1)css里单独写个color设置是字体颜色.(2)transparent 透明 是默认值,可以不写 (3)css盒子模型见w3c.每个浏览器的css盒子可能有所不同. 注意难点外边距合并.

(4)css定位. display 属性规定元素应该生成的框的类型。clear 属性规定元素的哪一侧不允许其他浮动元素。

v5

v5消除了我在v1提出的第一个问题,它用小图片代替原来难看的文字链接.作者直接是在每个<a>里加了img标签. 注意用css的display把他们变成inline元素.

下面来分析代码:

(1)假如没有JavaScript怎么办?    答:只要链接正确,html是解释执行的.

(2)怎么实现结构行为分离? 答:去掉事件处理函数,每个链接加个类(最好的办法是给ul加个属性,因为链接都包含在ul里,ul是最小包含这些事件处理链接的).那么我们就要把事件处理写在js里了.当然没js就不会触发这些行为了.问题来了,怎么在js里让链接和showPic联系起来呢.

(3)预留后路

(4)

但是

详情见http://www.jb51.net/article/21707.htm

(5)

但如果找不到那张占位图呢.

在showPic中判定是否有占位图,如果有没有就返回ture,它会按照这个链接被点击的情况采取行动.

如果此时你的img没有alt属性那么在网页中会有个难看的小占位标记.点击链接了会将该标记替换为你想要的图片.(alt属性的重要习惯,为每张图片设置alt)

有alt属性的话,图片会替换alt文字.(这不也算是一个好交互嘛)

那么问题来了为何只对占位符进行return true呢.我试着删掉desciption的return false.发现点击链接后原来的字消失了.(这也蛮诡异,可以留用)

我又删掉了description并将desciption的js判断后面的语句改为true.发现将按照浏览器默认行为工作了.这个不好.(更多的可能需要自己去试错)

(6)对showPic各属性检查,见后面的代码   //注意if else 可以替换为 ? :

(7)让按键盘也能切换图片 加上一句onkeypress,详情见代码. 注意我们已经实现了分离.否则源代码要分开写.但我发现这个功能及其不方便,切换图片每次非要用鼠标在页面上点一次再按其他键才能切换.而且作者也不怎么推荐用这个方法.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Image Gallery</title>
    <script type="text/javascript" src="scripts/showPic.js"></script>
    <link rel="stylesheet" href="styles/layout.css" type="text/css" media="screen" />
</head>
<body>
  <h1>Snapshots</h1>
  <ul id="imagegallery">
    <li>
      <a href="images/fireworks.jpg" title="A fireworks display">
        <img src="images/thumbnail_fireworks.jpg" alt="Fireworks" />
      </a>
    </li>
    <li>
      <a href="images/coffee.jpg" title="A cup of black coffee" >
        <img src="images/thumbnail_coffee.jpg" alt="Coffee" />
      </a>
    </li>
    <li>
      <a href="images/rose.jpg" title="A red, red rose">
        <img src="images/thumbnail_rose.jpg" alt="Rose" />
      </a>
    </li>
    <li>
      <a href="images/bigben.jpg" title="The famous clock">
        <img src="images/thumbnail_bigben.jpg" alt="Big Ben" />
      </a>
    </li>
  </ul>
  <img id="placeholder" src="images/placeholder.gif" alt="my image gallery" />
  <p id="description">Choose an image.</p>
</body>
</html>

View HTML

#imagegallery {
    list-style: none;
}

#imagegallery li {
  display: inline;
}

#imagegallery li a img {
    border: 0;
}

View CSS

function showPic(whichpic) {
  if (!document.getElementById("placeholder")) return true;
  var source = whichpic.getAttribute("href");
  var placeholder = document.getElementById("placeholder");
  placeholder.setAttribute("src",source);
  if (!document.getElementById("description")) return false;
  if (whichpic.getAttribute("title")) {
    var text = whichpic.getAttribute("title");
  } else {
    var text = "";
  }
  var description = document.getElementById("description");
  if (description.firstChild.nodeType == 3) {
    description.firstChild.nodeValue = text;
  }
  return false;
}

function prepareGallery() {
  if (!document.getElementsByTagName) return false;
  if (!document.getElementById) return false;
  if (!document.getElementById("imagegallery")) return false;
  var gallery = document.getElementById("imagegallery");
  var links = gallery.getElementsByTagName("a");
  for ( var i=0; i < links.length; i++) {
    links[i].onclick = function() {
      return showPic(this);
    }
    links[i].onkeypress = links[i].onclick;
  }
}

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != ‘function‘) {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}

addLoadEvent(prepareGallery);

View JS

(8)样式表才是解决v1我提出的去掉默认li前的. 的关键. 第一句取消 . 第二句 让它水平排列. 第三句感觉不明显,在盒子模型中看到每张图片的外边距从浏览器默认的1em变成了0.

v6

总算进化到v6了.该版本HTML和JS与前面相同.就css丰富了下.

body {
  font-family: Helvetica,Arial,serif;
  color: #333;
  background-color: #ccc;
  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;
}
#imagegallery {
  list-style: none;
}

#imagegallery li {
  display: inline;
}

#imagegallery li a img {
  border: 0;
}

View CSS

关键代码

background-color: #ccc;  页面的颜色变成好看的银色.

margin: 1em 10%;  放在body内的这句话,让页面上下差1em(影响不大),后面那个10%让页面居中在80%的空间内.

li里的 float left让页面图片的排列如此.其实我决定right好看点,但如果没的话,则如v5那样.

li里的padding: 1em; 让图片间隔开了.查看盒子模型可以看到li的填充加了1em. 但是同样的效果加边距或者加在内部的a或者img都可以实现,为什么加在最外面的那个li呢.

这篇博文我花了两天才写完,总结的经验就是多试错,会有意想不到的事情发生.

时间: 2024-10-18 01:01:59

JavaScript美术馆进化史的相关文章

JavaScript 异步进化史

前言 JS 中最基础的异步调用方式是 callback,它将回调函数 callback 传给异步 API,由浏览器或 Node 在异步完成后,通知 JS 引擎调用 callback.对于简单的异步操作,用 callback 实现,是够用的.但随着负责交互页面和 Node 出现,callback 方案的弊端开始浮现出来. Promise 规范孕育而生,并被纳入 ES6 的规范中.后来 ES7 又在 Promise 的基础上将 async 函数纳入标准.此为 JavaScript 异步进化史. 同步

【转】JavaScript 异步进化史

前言 JS 中最基础的异步调用方式是 callback,它将回调函数 callback 传给异步 API,由浏览器或 Node 在异步完成后,通知 JS 引擎调用 callback.对于简单的异步操作,用 callback 实现,是够用的.但随着负责交互页面和 Node 出现,callback 方案的弊端开始浮现出来. Promise 规范孕育而生,并被纳入 ES6 的规范中.后来 ES7 又在 Promise 的基础上将 async 函数纳入标准.此为 JavaScript 异步进化史. 同步

JavaScript编程艺术-第6章(JavaScript美术馆改进版)代码

基于[第4章(JavaScript美术馆)代码]进行改进(***HTML与JS分离***) (*亲测可用) HTML: JS: CSS:

JavaScript网站设计实践(五)编写photos.html页面,实现点击缩略图显示大图的效果

原文:JavaScript网站设计实践(五)编写photos.html页面,实现点击缩略图显示大图的效果 一.photos.html页面,点击每一张缩略图,就在占位符的位置那里,显示对应的大图. 看到的页面效果是这样的: 1.实现思路 这个功能在之前的JavaScript美术馆那里已经实现了. 首先在页面中使用ul列表显示出所有的缩略图,然后使用JavaScript,for循环检查出当前点击的是哪一张图片,最后把这张图片给显示出来. 用到三个函数:显示图片函数.创建占位符预装图片.点击显示图片

JavaScript编程艺术-第7章代码汇总(2)

[7.4节] 重回"JavaScript美术馆"代码 ***亲测可用*** HTML: JS:

《javascript dom编程艺术》笔记(二)——美术馆示例

这几天把这本书看完了,里面大部分知识我已经会了,所以看得就略简单,好多地方都没有再去动手去做,我知道这样是不对的,以后补吧. 现在我要做的是把这本书的笔记完结掉,不然总觉得有啥事没有做. 这个版本不是书中的最后版本,好像是第二版吧.后面还有动态创建结点的一版本,我已经在别的地方实践过了,就不再做了. 只贴出两个函数. //显示图片方法 function showPicture (whichpic) { //综合绑定的事件考虑,条件执行失败,希望浏览器可以让用户打开图片,因此在onclick处re

【JavaScript 】for 循环进化史

ECMAScript 6已经逐渐普及,经过二十多年的改进,很多功能也有了更成熟的语句,比如 for 循环 这篇博客将介绍一下从最初的 for 循环,到 ES6 的 for-of 等四种遍历方法 先定义一个数组: const myArray = [1, 5, 9]; myArray.name = 'wise' 在控制台中打印这个数组,会看到这个数组的全貌: 一. for 相信大部分开发工作者,最初遍历数组的方法都是使用 for 循环: for ( let i = 0; i < myArray.le

javascript 4.1 美术馆

1.把images文件夹放在html文件同一文件夹子目录下,可以在html中引用图片 例如<a href="images/rose.jpg" title="A red,red rose">Rose</a> 2.占位符:<img id="placeholder" src="images/zwf.jpg" alt="my image gallery" /> 对占位符设置id,

美术馆(完)

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <title>美术馆</title