《DOM Scripting》学习笔记-——第五章、第六章 案列改进

第四章的案例代码可以得到更好的改进。例如:预留退路、向后兼容性和分离js。

原html代码:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Document</title>
 6 </head>
 7 <body>
 8   <h1>Snapshots</h1>
 9   <ul>
10     <li>
11       <a href="images/rose.jpg" onclick="showPic(this);return false" title="A fireworks display">Fireworks</a>
12     </li>
13     <li>
14       <a href="images/rose.jpg" onclick="showPic(this);return false" title="A cup of black coffee">
15  Coffee</a>
16     </li>
17     <li>
18       <a href="images/rose.jpg" onclick="showPic(this);return false" title="A red, red rose">Rose</a>
19     </li>
20     <li>
21       <a href="images/bigben.jpg" onclick="showPic(this);return false" title="The famous clock">
22  Big Ben</a>
23     </li>
24  </ul>
25 
26   <img id="placeholder" src="images/placeholder.gif" alt="my image gallery" />
27   <p id="description">Choose an image.</p>    
28 
29 </body>
30 </html>

原js代码:

1 function showPic(whichpic) {
2 var source = whichpic.getAttribute("href");
3 var placeholder = document.getElementById("placeholder");
4 placeholder.setAttribute("src",source);
5 var text = whichpic.getAttribute("title");
6 var description = document.getElementById("description");
7 description.firstChild.nodeValue = text;
8 }

一、解决预留退路问题:
     没有使用js伪协议,即使js功能被禁用,a链接仍可以链接到图片,虽然与js在当前页面上切换显示新图片的效果略差一些,但网页的基本功能没有受到损害,页面上的所有内容都可以访问。
二、解决分离js的问题:
     1、onclick事件处理函数直接插到html文档里,不符合“分离js”原则。
    解决:
     (1)找到“挂钩”把js代码与html文档中有关标记关联起来。
            a、给每个链接添加一个class属性。(较麻烦)
            b、给ul加一个id(id=“imagegallery”)
    (2)添加事件处理函数,该函数需要具有以下功能:
            a、检查当前浏览器是否理解getElementsByTagName()方法。
            b、检查当前浏览器是否理解getElementById()方法。
            c、检查当前网页是否包含着一个id属性值是“imagegallery”的元素。
            d、构造一个循环来对“Imagegallery”元素中的链接进行遍历处理。
            e、对onclick事件处理函数进行设置,让它在有关链接被点击时完成以下操作:把这个链接作为参数传递给showpic()函数;取消链接被点击时的默认行为,不让浏览器打开这个链接。


           ①进行必要的检查
              

1 if (!document.getElementsByTagName) {
2 return false;
3 }
4 if (!document.getElementById) {
5 return false;
6 }

          或

1 function prepareGallery() {
2 if (!document.getElementsByTagName) return false;
3 if (!document.getElementById) return false;
4 if (!document.getElementById("imagegallery")) return false;

结构化程序设计(structed programming)原则:每个函数应该只有一个入口点和一个出口点。
但是过分拘泥以上原则会使得代码难以阅读。所以一般而言,同一个函数有多个出口点的情况是可以接受的,但前提是它们应该集中出现在函数的开头部分。如第二种方法所示。
         ②创建必要的变量

1 var gallery = document.getElementById("imagegallery");
2 var links = gallery.getElementsByTagName("a");

        ③创建循环

for ( var i=0; i < links.length; i++) {

        ④完成必要的操作

1 links[i].onclick = function() {
2 showPic(this);
3 return false;
4 }

匿名函数一般用于只出现一次的函数

 

 1 function prepareGallery() {
 2 if (!document.getElementsByTagName) return false;
 3 if (!document.getElementById) return false;
 4 if (!document.getElementById("imagegallery")) return false;
 5 var gallery = document.getElementById("imagegallery");
 6 var links = gallery.getElementsByTagName("a");
 7 for ( var i=0; i < links.length; i++) {
 8 links[i].onclick = function() {
 9 showPic(this);
10 return false;
11 }
12 }
13 }

       ⑥把多个js函数绑定到onload事件处理函数上。在html文档完成加载之前,DOM是不完整的,必须使这个函数只在网页加载完毕之后才得到执行。网页加载完毕时会触发一个onload事件,这个事件与window对象相关联。

1 window.onload = function() {
2 firstFunction();
3 secondFunction();
4 }

       或者使用addLoadEvent()函数

 1  function addLoadEvent(func) {
 2  var oldonload = window.onload;
 3  if (typeof window.onload != 'function') {
 4  window.onload = func;
 5  } else {
 6  window.onload = function() {
 7  oldonload();
 8  func();
 9  }
10  }
11  }
  addLoadEvent(firstFunction);
  addLoadEvent(secondFunction);

三、js函数的优化

1、不要做太多假设
showPic()函数没有进行任何测试和检查。虽然showPic()函数由prepareGallery()函数调用,在prepareGallery()函数的开头对getElementById()和getElementsByTagName()等DOM方法是否存在进行过检查,但是在showPic()函数中仍存在太多假设,比如对于id属性值等于placeholder和description的元素,函数并未对这些元素进行检查。

 1 function showPic(whichpic) {
 2 if (!document.getElementById("placeholder")) return true;//如果不存在placeholder,图片切换不成功,则返回true,通过a链接点击到图片
 3 var source = whichpic.getAttribute("href");
 4 var placeholder = document.getElementById("placeholder");
 5 placeholder.setAttribute("src",source);
 6 if (!document.getElementById("description")) return false;//已经读到此说明之前图片切换成功,所以要返回false,使a链接不能使用。
 7 var text = whichpic.getAttribute("title");
 8 var description = document.getElementById("description");
 9 description.firstChild.nodeValue = text;
10 return false;//已经读到此说明之前图片切换成功,所以要返回false,使a链接不能使用。
11 }

此时prepareGallery()函数的代码:

 1 function prepareGallery() {
 2 if (!document.getElementsByTagName) return false;
 3 if (!document.getElementById) return false;
 4 if (!document.getElementById("imagegallery")) return false;
 5 var gallery = document.getElementById("imagegallery");
 6 var links = gallery.getElementsByTagName("a");
 7 for ( var i=0; i < links.length; i++) {
 8 links[i].onclick = function() {
 9 return showPic(this);
10 }
11 }
12 }
原文地址:https://www.cnblogs.com/yangfang228/p/6028161.html