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

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

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

     <!DOCTYPE html>
     <html lang="en">
         <head>
             <meta content="text/html; charset=utf-8" http-equiv="content-type"></meta>
             <title>

                 Image Gallery

             </title>
         </head>
         <body>
             <h1>

                 Snapshots

             </h1>
             <ul>
                 <li>
                     <a title="A fireworks display" href="images/fireworks.jpg">

                         Fireworks

                     </a>
                 </li>
                 <li>
                     <a title="A cup of black coffee" href="images/coffee.jpg">

                         Coffee

                     </a>
                 </li>
                 <li>
                     <a title="A red, red rose" href="images/rose.jpg">

                         Rose

                     </a>
                 </li>
                 <li>
                     <a title="The famous clock" href="images/bigben.jpg">

                         Big Ben

                     </a>
                 </li>
             </ul>
         </body>
     </html>

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

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

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

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

 <!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>
 </head>
 <body>
   <h1>Snapshots</h1>
   <ul>
     <li>
       <a href="images/fireworks.jpg" title ="A fireworks display" onclick="showPic(this); return false;">Fireworks</a>
     </li>
     <li>
       <a href="images/coffee.jpg" title="A cup of black coffee" onclick="showPic(this); return false;">Coffee</a>
     </li>
     <li>
       <a href="images/rose.jpg" title="A red, red rose" onclick="showPic(this); return false;">Rose</a>
     </li>
     <li>
       <a href="images/bigben.jpg" title="The famous clock" onclick="showPic(this); return false;">Big Ben</a>
     </li>
   </ul>
   <img id="placeholder" src="data:images/placeholder.gif" alt="my image gallery" />
 </body>
 </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是在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;

v3已经将要实现的功能实现了,v4算是美化页面.下面是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 {
 ;
 }
 li {
   float: left;
   padding: 1em;
   list-style: none;
 }
 img {
   display:block;
   clear: both;
 }

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

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

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="data:images/thumbnail_fireworks.jpg" alt="Fireworks" />
      </a>
    </li>
    <li>
      <a href="images/coffee.jpg" title="A cup of black coffee" >
        <img src="data:images/thumbnail_coffee.jpg" alt="Coffee" />
      </a>
    </li>
    <li>
      <a href="images/rose.jpg" title="A red, red rose">
        <img src="data:images/thumbnail_rose.jpg" alt="Rose" />
      </a>
    </li>
    <li>
      <a href="images/bigben.jpg" title="The famous clock">
        <img src="data:images/thumbnail_bigben.jpg" alt="Big Ben" />
      </a>
    </li>
  </ul>
  <img id="placeholder" src="data: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:;
}

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了.该版本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:;
}
li {
  float: left;
  padding: 1em;
  list-style: none;
}
#imagegallery {
  list-style: none;
}

#imagegallery li {
  display: inline;
}

#imagegallery li a img {
  border:;
}

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呢.

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

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

  1. 【转】JavaScript 异步进化史

    前言 JS 中最基础的异步调用方式是 callback,它将回调函数 callback 传给异步 API,由浏览器或 Node 在异步完成后,通知 JS 引擎调用 callback.对于简单的异步操作 ...

  2. 实践javascript美术馆的小案例,学习到的东西还是蛮多的,包括javascript编程中的预留退路、分离javascript、以及实现向后兼容等

    javascript美术馆(改进2) 一.javascript编程过程中的好习惯 1.实现预留退路 js被禁掉,图片也可以显示出来,href属性带有图片路径 <script src=" ...

  3. JavaScript 异步进化史

    前言 JS 中最基础的异步调用方式是 callback,它将回调函数 callback 传给异步 API,由浏览器或 Node 在异步完成后,通知 JS 引擎调用 callback.对于简单的异步操作 ...

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

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

  5. JavaScript 编程艺术-第4章(JavaScript美术馆)代码

    功      能:在同一个网页上切换显示不同的图片与文本(*亲测可用) 使用属性: a) document.getElementById(" ") ——返回一个与给定的id属性值的 ...

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

    一.photos.html页面,点击每一张缩略图,就在占位符的位置那里,显示对应的大图. 看到的页面效果是这样的: 1.实现思路 这个功能在之前的JavaScript美术馆那里已经实现了. 首先在页面 ...

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

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

  8. ECMAScript进化史(1):​话说Web脚本语言王者JavaScript的加冕历史

    互联网起火-Web时代的来临 在行文之前,反手就安利一下<浏览器史话中chrome霸主地位的奠定与国产浏览器的割据混战>. 浏览器始祖NCSA Mosaic在1993年1月发布(于1992 ...

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

    这几天把这本书看完了,里面大部分知识我已经会了,所以看得就略简单,好多地方都没有再去动手去做,我知道这样是不对的,以后补吧. 现在我要做的是把这本书的笔记完结掉,不然总觉得有啥事没有做. 这个版本不是 ...

随机推荐

  1. meta基础知识

    H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=device-width,initia ...

  2. 【IHttpHandler】HttpModule的认识

    HttpModule是向实现类提供模块初始化和处置事件.当一个HTTP请求到达HttpModule时,整个ASP.NET Framework系统还并没有对这个HTTP请求做任何处理,也就是说此时对于H ...

  3. HBase简介(很好的梳理资料)

    http://www.tuicool.com/articles/iieIz2 一.   简介 history  started by chad walters and jim 2006.11 G re ...

  4. Volume serial number could associate file existence on certain volume

    When it comes to lnk file analysis, we should put more emphasis on the volume serial number. It coul ...

  5. sed的惯常用法

    1:注释掉某一行这个经常会遇到的,把配置文件里某一行注释掉.让他不起作用.sed -i -e ’121 s/^/#/’ /usr/local/apache2/conf/httpd.conf上面一行命令 ...

  6. 简单linux字符设备驱动程序

    本文代码参考<LINUX设备驱动程序>第三章 字符设备驱动程序 本文中的“字符设备”是一段大小为PAGE_SIZE的内存空间 功能:向字符设备写入字符串:从字符设备读出字符串 代码: 1. ...

  7. 关于VS2012下安装破解文件Visual Assit X的一点说明

    今天在使用Visual Studio 2012的时候,编写代码的助手Visual Assit X突然提示我说,试用期已过,要求我输入一个注册码,我靠,这货不是几个月前已经破解了吗,怎么今天傻不愣登的提 ...

  8. 访问svc 文件,编译器错误消息: CS0016,未能写入输出文件

    编译错误              说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码.             编译器错误消息: CS0016: 未 ...

  9. 使用WIF实现单点登录Part IV —— 常见问题

    InvalidOperationException: ID1073: 尝试使用 ProtectedData API 解密 Cookie 时出现 CryptographicException (有关详细 ...

  10. SQL语句的执行顺序

    一.sql语句的执行顺序 (8)SELECT (9) DISTINCT (11) <TOP_specification> <select_list> (1) FROM < ...