《JavaScript DOM编程艺术》学习笔记<一>

来源:互联网 发布:产品研发部 数据公司 编辑:程序博客网 时间:2024/05/16 06:05

        学习这本书的目的是想扎实一下自己在前端开发技术方面的基础,因为目前自己虽然可以利用JavaScript、jQuery等技术解决遇到的问题,但总有一种只是浮在表面上的不安感,我觉得这主要是自己没有去系统学习相关知识的缘故,只是在W3CSchool上学习了基本语法之后就开始使用,等遇到问题之后再随便百度一下,而这种做法自己一般很难记住解决问题的方法,更别说为什么这么做可以解决遇到的问题,等下次碰到完全一样的问题时还是得求助百度,效率低下且没有意义。我应该算是这种做法的直接受害者,就算到目前我仍然无法清晰的指出Web前端开发有哪些基础的技术,以及那些技术术语作何解释,比如,DOM是什么意思?它有什么用处?我在编写JavaScript时有跟它打交道吗?而这也是我学习本书的最直接原因。

       也许是自己想解开上述疑惑的想法太迫切了,也许是书的内容不算太难(毕竟是入门书籍),昨天下午开始翻看之后就没停下来,一直看到晚上将近十二点才回去,现在看了六章,三分之一强。因为这个过程中动手较少,所以我想还是趁热打铁抓紧时间把现在的想法记录一下,要不然又没有什么意义了。

        之前我最大的困惑就是在实现网页动态交互效果时感觉明明采用的完全是JavaScript代码,丝毫没有DOM的影子,但不管是书上还是网上凡是有JavaScript的地方总是会伴随着DOM,这让我很疑惑。我只知道DOM是Document Object Model的简称,也就是文档对象模型的意思,但这些还是无法让我认识到DOM的意义。本书在第一章就明确的解释了这个问题。要了解DOM的真正意义,先了解它为什么会出现有很大帮助,但我觉得还是应该先对DOM本身的概念进一步了解一下会比较好。比较书面地讲,DOM是一套对文档的内容进行抽象和概念化的方法。可能还是比较难理解,我之前也是,我当时困惑的是一个“模型”怎么会跟“方法”联系在一起?但是这样一想就好理解了:先不管前面的“DO”,只看“M”,但凡我们讲到Model(模型)不都会直接想到抽象化和概念化吗?比如数据库里的概念模型、逻辑模型,再比如飞机模型、汽车模型等等。但是你在建立或制造这些“模型”的时候不都得先想一下怎么建吗?这就涉及到一个方法的问题,所以才会出现上述描述中的“方法”一词。这之后再来看前面的“D”和“O”,分别是文档和对象的意思,我觉得这两个词放在一起看更容易理解。其实放在一起我还是无法理解,但是作者在书中类比了一下我顿时明白了。作者拿“世界对象模型”进行类比,也就是把世界中的一切物体都当做对象,然后与人交流的时候一般不会出现问题(这里不考虑语言不通的情况),比如别人问你:昨天买了什么:你回答说:我买了苹果。这个苹果就是一个对象,或者说“苹果”一词就是对苹果实体的抽象模型,而这么说对方几乎可以肯定是可以理解什么意思的,为什么?这个为什么的原因就是理解DOM的根本所在,也是DOM具有那么大意义的原因所在。再回到前面苹果的例子上,我们平时这么交流是基于这样一个前提:双方对“苹果”一词的理解是一致的。所谓一致也就是标准,而DOM就是这样一个标准。好了,有了这些准备知识以后,再来说DOM产生的原因就好理解了。

        我们有时会困惑DOM和JavaScript的关系,它们的产生有先后关系吗?如果有,谁先谁后?根据我的理解它们是同时产生的。最早的JavaScript出现在1995年,由Netscape和Sun合作开发,它的目的就是提高网页与用户的交互性,而就在这最早的JavaScript的版本中已经包含了初级的DOM,为什么?我们知道,所谓的网页交互性,当时来讲无非是响应鼠标和键盘的各种操作,比如左键单击、左键双击、Tab键转移焦点、Enter键触发等等,获取这些事件相对比较容易,但是交互性的另一个重要内容是获取交互的目标,也就是对象,比如是单击的按钮还是超链接,抑或是图片,Enter键按下时焦点在哪个元素(也就是对象)上,等。这都是设计JavaScript预言时必须考虑的东西,不管是上面最早的Netscape的JavaScript还是后来追赶而来的微软的VBScript(即JScript),或者是后来的JavaScript的标准ECMAScript。如何获取事件发生的对象,以及需要改变内容或样式的对象呢?方法很多,但首先需要考虑的是如何表示这样一个文档,即文档的结构如何表示,是一维的还是二维的,采用不同的表示形式将导致不同的实现方法。在当时浏览器之争那么激烈的年代,Navigator和IE各自为营,期望他们采用相同的方法简直是天方夜谭,更别说定义一致的API(这个如果难理解,先别急,后面还会说到)了。事实就是这样,那段时间这两种浏览器分别定义了自己的DOM,比如Netscape就采用了一种层的概念,我们知道它与我们现在理解的文档结构表示形式是不同的(现在采用的数结构)。这也就造成了如果想在不同浏览器上实现相同效果必需实现两套甚至更多方案的现象。这种不利于自然发展的现象必然会被社会淘汰,哪怕你的势力如微软那样强大,一样得屈服于自然规律。所以一些Web设计行业的有识之士就联合起来抵制这种现象。解决这一问题的途径自然而然的就想到制定统一的标准,然后不同的浏览器厂商都遵循这一标准,JavaScript开发者就不需要同时实现两套方案了。这时首先要统一的标准肯定是JavaScript了,ECMAScript就是它的标准,虽然它的名字没有流传下来。但是JavaScript只是一门语言,无非是一些关键词、语法方面的标准,通过我们上面的描述,为了实现交互效果我们还必须统一如何获得对象等的方法,这里的“方法”我们就可以理解为JavaScript的API了,即应用程序编程接口。想想我们使用C++或Java时无时无刻不再使用各种API,它是我们完成工作的根本,没有他们我们几乎无法完成任何工作。同时,提供这样一套“方法”的前提有一个设计的问题,或者说统筹的问题,这样一套API接口无非是函数的名称以及意义说明,我们每个人都可以制定出这样一个标准,但是基于不同的设计原理制定出的标准或者说API名称肯定是不一样的。这就是DOM的意义。经过前面的讲解,我们应该有了这样一个认识,DOM本身不是标准,可以存在很多种DOM,而我们所要讲解的有意义的DOM应该是W3C制定的DOM,我们为了简单起见就直接称之为DOM了。W3C制定的这套DOM标准规定了一系列的API函数接口名称及其意义,比如setAttribute/getAttribute等,更重要的是这套标准将一个HTML文档表示成一个树结构,定义这样一个结构对提供API结构具有决定性的作用,比如这样一个API:getSibling,采用不同的结构它返回的内容是不同的,也就是有二义性,所以要先定义一个结构。这也就解释了为什么说DOM是一套API,它本质上就是一组函数,每个JavaScript语言都要去实现他们并按照要求接受或返回某种类型的结果。我之前之所对JavaScript和DOM比较困惑,无法感觉到DOM的存在,其实是把二者混在一起了,其实无时无刻不在使用DOM。

最后需要强调一点是,W3C制定的这个DOM标准其目的不仅仅在于通过JavaScript处理HTML文档,它有着更大的野心,用书上的话讲就是:“DOM脚本程序设计”涵盖了使用任何一种DOM API的程序设计语言去处理任何一种标记文档。而JavaScript只是其中一种程序设计语言,HTML文档也只是其中一种标记文档。我简单试了一下,你在HTML文档中加入不存在的标签,然后使用JavaScript在脚本中利用现有getElementsByTagName一样可以处理,看来此言非虚。

总之,没有DOM就没有标准,没有标准如今的Web开发将异常困难。可以说DOM的出现对于JavaScript的发展至关重要。

好了,用了那么大的篇幅来讲解什么是DOM,相信我自己和看到这篇文章的都会清楚了。然后是本文其他章节的内容。

本书第二章讲的是JavaScript的基本语法,与W3CSchool上的教程差不多,甚至还要更简单,无非是变量、操作符、条件语句、循环语句、函数等等,比较简单。其中有两点比较重要,其中一个是变量作用域的问题,没有使用var关键词生命的变量都将被视为全局变量,无论是在函数内还是函数外,而出现在函数外的变量无论是否使用var关键词都被视为全局变量;另一个是对象的问题,JavaScript中包含三种对象:用户自定义对象、内建对象和宿主对象。

第三章讲述的DOM的原理以及几个API函数的用法。其中一点比较重要,即节点的概念,DOM中包含三类节点:元素节点、文本节点以及属性节点。如果使用childNodes获取子节点数目时其结果一定会出乎很多人的意料,因为它会包括文本节点。

第四章作者利用上面给出的几个API设计实现了一个图片库的例子,比较简单。

第五章是非常重要的一章,即最佳实践。我到今天才明白所谓最佳实践就是作者手把手的把自己那么多年工作、学习、思考的经验交给你。我们平时经常抱怨实际工作中遇到难题没有大牛帮自己解答,或者抱怨无法了解那些大牛是如何解决实际问题,或者他们是如何实际写代码的,最佳实践其实就是这些东西。不知道《Effective C++》是不是如此?我要去验证。作者在这一章提出了解决JavaScript编程中需要考虑、非常重要,但是又被大多数人忽略的基本问题,即平稳退化、分离JavaScript、向后兼容、性能考虑。也许是术语的问题、也许是翻译的问题,相信很多人不能理解平稳退化是什么意思?其他三个应该都可以理解。所谓平稳退化就是指我们在设计带有JavaScript的网页时要考虑如果用户的客户端不支持JavaScript你所设计的网页还会正常运行吗?

意思知道了,那如何去实现呢?说实话,我刚看到时甚至觉得怎么可能呢?这怎么可能实现,甚至觉得除了性能自己可以稍微优化一些,其他三项都不可能完成。但作者实现了,只能说自己的知识太浅薄了。方法其实也很简单,相信大多数人都可以理解,但很多人都想不到,或者很多人根本就没有去想过。简单之处见功底啊!

先说分离JavaScript代码,我当时觉得这个我也会啊,使用<script src一下不就可以了,但作者的意思并非仅仅如此,作者是想让网页中彻底消失javascript代码,甚至是onclick这种单词。其方法是借鉴CSS的技术,采用id或class对标签进行标注然后在外部的javaScript文件中获取这些元素。

然后是平稳退化,这里作者采用的是超链接的例子,其他标签是否也存在这样的应用问题一起解决方法是否如此我还没考虑。这个例子是点击超链接在当前页面的小窗口中显示目标内容,采用JavaScript代码可以实现,但是要考虑客户端不支持JavaScript的情况下用户是否仍然至少可以浏览目标内容。方法就是在a标签的href中给出正常的目标连接,然后在onclick属性中给出调用函数,别忘了要添加return false;语句。这一方法与上述方法结合在一起更好了。

接着是向后兼容,即要考虑某些API函数在老版本的浏览器中是否支持,这种情况很普遍,因为有些API是新加进标准的。方法是先判断某一方法在该浏览器中是否存在,如果不存在则退出该脚本函数。实现判断的方法DOM出现之前采用的是”浏览器嗅探技术“,即先判断浏览器的品牌和版本信息然后判断目标API函数是否可以执行。这种技术一般会导致大量且复杂的判别代码。而现在可以采用的是一种称为”对象检测“的技术。因为在DOM中一切皆为对象,包括函数,所以我们可以采用如下的语句判断某函数在目标浏览器中是否存在if(method),注意函数名后不要加括号。一般的写法是if(!method) return false;,这主要是为了代码的简洁。能够采用这种方法与JavaScript中处理布尔类型的方法有关,在JavaScript中,除了false、null、0以及”“被视为false之外,其他一切被视为true,所以如果某个对象存在则返回false,如果某个对象不存在,这种语句会把它当做全局变量,由它是第一次出现,自然为null,因为返回false。

最后是性能的考虑,主要从以下几个方面考虑:尽量少访问DOM和尽量少使用HTML标记;合并和放置脚本(</body>之前);压缩脚本(有很多压缩工具)。

第六章作者采用上述的最佳实践对第四章的实例进行了改进,学到了很多。真心佩服作者的细心及细致,考虑问题非常全面。作者会考虑代码中每一个语句可能出现的例外情况,虽然代码会多出很多,但是却保证了网页的完美显示。在这一章,作者特别提到了是否要处理onkeypress的事件,最后得出的结论是不处理,这是因为onclick事件很”聪明“,它会同时接受onkeypress事件。然后作者还提到了DOM-Core和HTML DOM的问题。上面已经讲过W3C制定DOM标准并不只是为了解决了HTML问题,所以我们可以将W3C制定的标准成为DOM-Core,即它是所有DOM实现必需支持的核心部分,但除此之外不同的DOM可以根据自身情况有所增加。比如HTML,如果使用DOM-Core中的方法和属性其代码一般会很长,因此其自身提供了一些可以实现相同功能但会简单很多的方法。

以上就是我昨天学习的前六章的内容,内容不是太多,但是很有帮助。

0 0
原创粉丝点击