《JavaScriptDOM编程艺术》读后感2:第六章,一个常规事件的逻辑
在第二边学习《JavaScriptDOM编程艺术》时,我发现第6章(案例研究:图片库改进版)很有看头。它将我们之前的学习内容通过一个真实的案例融合起来,并且教导我们如何来做一个Javascript事件:
6.3它的JavaScript与HTML标记是分离的吗?
在前几章中,书给我们大体讲解了案例的部分,并且让我们学会了最基本的JavaScript事件的编写。而这章,它提出了“分离”的概念。
我们通常在web里面,只用一个ID就能和JavaScript形成挂钩。这个ID能很好的简化HTML的架构,使得结构层(HTML)看起来更清爽,而行为层(JavaScript)更专注于做它自己的事。
6.3.1增加事件处理函数
好了,下面就是“操刀”了,大家可以来重点看下思路:
-
检查点;
在一个function里面会用到很多get...类的命令,为了更好的兼容浏览器,我们往往会对我们即将使用的这些命令进行自检查。当浏览器“认识”这些命令的时候,function才会进行下去,不认识的时候就跳出。
当然,学校教的原则是:“函数应该只有一个入口和出口。”但我们的做法其实已经违背了这一做法,书中作者提出的观点是:“如有一个函数有多个出口,只要这些出口集中出现在函数的开头部分,就是可以接受的。”
if (!document.getElementById) return false; if (!document.getElementById("imagesgallery")) return false; if (!document.getElementsByTagName) return false;
-
变量名里有什么;
我们如果不想重复输入那些get..命令的话,就必须想好创建一些变量来简化它。这样,写起事件时,就可以避免代码过长而引起的阅读困难了。
var gallery = document.getElementById('imagesgallery'); var links = gallery.getElementsByTagName('a');
-
遍历;
说实话,这词我真不知道翻译是如何理解的。原作想表达的意思应该是通过for来获取元素。
不过我在使用sublime编辑时候,发现Snippets提供了一个更好的处理方法,我将这两个一起发出来,供大家挑选使用吧:
for (var i = links.length - 1; i >= 0; i--) { // 我编辑时的处理方法 for (var i = 0;i< links.length; i++) { // 书中的方法
-
改变行为;
顾名思义,当我们用for获取了元素后,我们是希望来改变点什么。书中是给它增加了一个点击(onchilck)的事件(function)。并且调用了一个显示的函数:showPic()(这个函数在本文中未涉及,大家只要知道是一个显示图片的函数就可以了)。完成后的代码就是这样:
links[i].οnclick=function () { showPic(this); return false; }
-
完成JavaScript函数;
function function_name() { if (!document.getElementById) return false; if (!document.getElementById("imagesgallery")) return false; if (!document.getElementsByTagName) return false; var gallery = document.getElementById('imagesgallery'); var links = gallery.getElementsByTagName('a'); for (var i = links.length - 1; i >= 0; i--) { links[i].οnclick=function () { showPic(this); return false; } } }
上述的5点其实在我们写事件(function)时不知不觉都会用到,对于一个初学者来说,这样的归纳的确很重要,只要你按照这样的思路来写,能很方便的写出优秀的JavaScript事件的。
6.3.2共享onload事件
之前学习中提到,一般的JavaScript事件是在web加载结束后才开始执行的,所以我们理所当然的会加一个onload的事件:
window.οnlοad=function () {
changePic();
function_name();
}
上述方法对于这个小事件已经足够了,而书中又给我们衍生出了一个addLoadEvent函数。这个函数被广泛用于JavaScript的开发中,逻辑和代码如下:
-
把现在的window.onload事件处理的值存在变量oldinload;
-
如果在这个处理函数上还没有绑定任何函数,就像平常那样把新函数增加给它;
-
如果在这个处理函数上已经绑定了一些函数,就把新函数追加到现有指令的末尾。
function addLoadEvent(func){
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.οnlοad=func;
}else{
window.οnlοad=function () {
oldonload();
func();
}
}
}
//使用方法
addLoadEvent(changePic);
addLoadEvent(function_name);
6.4不要做太多的假设
这个我也还没理解透彻,它重点是在研究return true;
到底应该是由哪个函数来实现的。如果有明白的请留言。
6.5优化
优化部分重点讲解了是如何出来一些逻辑判断的if的,并且给了一个一行简化的操作模式:判断一个值?真的运行:假的运行;
variable = condition ? if true : if false ;
中间的《6.6键盘访问》和《6.7把JavaScript与CSS结合起来》跳过,这两个内容有兴趣的可以自己阅读下。
6.8DOM Core和HTML-DOM
给我们编写事件时,常用到getElementById;getElementByTagName;getAttribute;setAttribute
。这些方法都是DOM Core的组成部分。他们的用途也非仅限于处理网页。
而HTML-DOM给我们提供了一个对象,我们可以把比较繁琐的get进行简单,就像下面这两个方式在web处理上是等同的:
element.getAttribute("src");// DOM Core命令
element.src;// HTML-Core 命令
作者和我都建议大家使用DOM Core命令来编写代码,虽然它有点沉闷,但它熟悉以后更容易使用,使用的范围也更广。
小节
看书做归纳对于学习来说的确是一个好事,通过自我对书中讲解的实施,我们可以更快的掌握书中的内容。这个文章中,我学习后编写的代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Image Gallery</title> </head> <body> <h1>Snpshots</h1> <ul id="imagesgallery"> <li><a href="images/1.jpg" οnclick="changePic(this); return false;">jpg1</a></li> <li><a href="images/2.jpg" οnclick="changePic(this); return false;">jpg2</a></li> <li><a href="images/3.jpg" οnclick="changePic(this); return false;">jpg3</a></li> <li><a href="images/4.jpg" οnclick="changePic(this); return false;">jpg4</a></li> </ul> <img src="images/none.jpg" alt="nonePic" id="placeholder"> <p id="urlHref">图片地址</p> <script type="text/javascript"> function changePic(whichpic) { if (!document.getElementById('placeholder')) return false; var ObjectHref=whichpic.getAttribute("href"); var placeholder=document.getElementById("placeholder"); placeholder.setAttribute("src",ObjectHref); if (!document.getElementById('urlHref')) { urlHref=document.getElementById("urlHref"); urlHref.childNodes[0].nodeValue=ObjectHref; } return false; } function function_name() { if (!document.getElementById) return false; if (!document.getElementById("imagesgallery")) return false; if (!document.getElementsByTagName) return false; var gallery = document.getElementById('imagesgallery'); var links = gallery.getElementsByTagName('a'); for (var i = links.length - 1; i >= 0; i--) { links[i].οnclick=function () { return changePic(this)? false : true; } // links[i].οnkeypress=links[i].onclick;未成功 } } window.οnlοad=function () { changePic(); function_name(); } // function addLoadEvent(func){ // var oldonload = window.onload; // if (typeof window.onload != 'function') { // window.οnlοad=func; // }else{ // window.οnlοad=function () { // oldonload(); // func(); // } // } // } </script> </body> </html>