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>
View Code

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

 缺点: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>
View Code

 

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 }
View Code

 

注意(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:

你可能感兴趣的:(JavaScript)