JavaScript DOM 编程艺术(第2版)读书笔记(5)
最佳实践
平稳退化
网站的访问者完全有可能使用的是不支持Javascript的浏览器,还有一种可能是虽然浏览器支持Javascript,但用户已经禁用它了。如果没有考虑到这种情况,人们在访问你们的网站时就有可能遇到各种各样的麻烦,并因此不再来访问你们的网站。
如果正确使用了Javascript脚本,就可以让访问者在他们的浏览器不支持Javascript的情况下仍能顺利地浏览你的网站。这就是所谓的平稳退化,就是说,虽然某些功能无法使用,但最基本的操作仍能顺利完成。
下面来看一个在新窗口中打开一个链接的例子:
function popUp(winURL){
window.open(winURL,"popup","width=320, height=480");
}
<a href="#" onclick="popUp('http://www.example.com/'); return false;">Example</a>
在这个实例中,实际工作都由onclick属性负责完成,不能平稳退化。
在链接里把href属性设置为真实存在的URL地址,让它成为一个有效的链接:
<a href="http://www.example.com/" onclick="popUp('http://www.example.com/'); return false;">Example</a>
或者
<a href="http://www.example.com/" onclick="popUp(this.getAttribute('href')); return false;">Example</a>
或者
<a href="http://www.example.com/" onclick="popUp(this.href); return false;">Example</a>
这三种方法都是可以的。
在把href属性设置为真实存在的URL地址之后,即使Javascript已被禁用,这个链接也是可用的。虽然这个链接在功能上打了点折扣(因为它没有打开一个新窗口),但是它并没有彻底失效。这是一个经典的“平稳退化”的例子。
这个技巧最明显的不足是:每当需要打开新的窗口时,就不得不把Javascript代码嵌入标记文档中。如果能把包括事件处理函数在内的所有Javascript代码全部放在外部文件里,这个技巧将更加完善。
向CSS学习
我们经常会遇到一些几乎每个元素都带有style属性的Web文档,而这是CSS技术最缺乏效率的用法之一。真正能从CSS技术获益的方法,是把样式全部转移到外部文件中去。
文档结构和文档样式的分离可以确保网页都能平稳退化。
所谓“渐进增强”就是用一些额外的信息层去包裹原始数据。按照“渐进增强”原则创建出来的网页几乎都符合“平稳退化”原则。
类似于CSS,Javascript和DOM提供的所有功能也应该构成一个额外的指令层。类似于使用style属性,在HTML文档里使用诸如onclick之类的属性也是一种既没有效率又容易引发问题的做法。如果我们用一个“挂钩”,就像CSS机制中的class或者id属性那样,把Javascript代码调用行为与HTML文档的结构和内容分离开,网页就会健壮得多。那么怎么把上面示例中的Javascript代码分离出来呢?
<a href="http://www.example.com/" class="popup">Example</a>
在外部的Javascript文件里把一个事件添加到HTML文档中的某个元素上:
element.event = action...
关键是怎么把应该获得这个事件的元素确定下来。具体步骤如下:
(1)把文档里的所有链接全放入一个数组里;
(2)遍历数组;
(3)如果某个链接的class等于popup,就表示这个链接在被点击时应该调用popUp()函数。
下面是实现上述步骤的Javascript代码:
var links = document.getElementsByTagName("a");
for(var i=0;i<links.length;i++){
if(links[i].getAttribute("class")=="popup"){
links[i].onclick = function(){
popUp(this.getAttribute("href"));
return false;
}
}
}
还有个问题需要解决:如果把这段代码存入外部Javascript文件,它将无法正常运行。因为这段代码的第一行是:
var links = document.getElementsByTagName("a");
这条语句将在Javascript文件被加载时立刻执行。如果Javascript文件是从HTML文档的<head>部分用<script>标签调用的,它将在HTML文档之前加载到浏览器里。同样如果<script>标签位于文档底部</body>之前,就不能保证哪个文件最先结束加载(浏览器可能一次加载多个)。因为脚本加载时文档可能不完整,所以模型也不完整。没有完整的DOM,getElementsByTagName等方法就不能正常工作。
必须让这些代码在HTML文档全部加载到浏览器之后马上开始执行。还好,HTML文档全部加载完毕时将触发一个事件,这个事件有它自己的事件处理函数。我将把我的Javascript代码打包在prepareLinks函数里,并将这个函数添加到window对象的onload事件上去。这样一来,DOM就可以正常工作了:
window.onload = prepareLinks;
function prepareLinks(){
var links = document.getElementsByTagName("a");
for(var i=0;i<links.length;i++){
if(links[i].getAttribute("class")=="popup"){
links[i].onclick = function(){
popUp(this.getAttribute("href"));
return false;
}
}
}
}
别忘记把popUp函数也保存到那个外部Javascript文件里去。
向后兼容
你的网站的访问者很可能未启用Javascript功能,而且不同的浏览器对Javascript的支持程度也不一样。绝大多数浏览器都能或多或少地支持Javascript,而绝大多数现代的浏览器对DOM的支持都非常不错。但比较古老的浏览器却很可能无法理解DOM提供的方法和属性。因此,即使某位用户在访问你的网站时使用的是支持Javascript的浏览器,某些脚本也不一定能正常工作。
针对这一问题的最简单的解决方案是,检测浏览器对Javascript的支持程度。
if(!getElementsByTagName || !getElementById) return false;
按照这一思路,在用来把onclick事件添加到链接上去的网页加载脚本里插入一条if语句。
window.onload = prepareLinks;
function prepareLinks(){
if(!document.getElementsByTagName) return false;
var links = document.getElementsByTagName("a");
for(var i=0;i<links.length;i++){
if(links[i].getAttribute("class")=="popup"){
links[i].onclick = function(){
popUp(this.getAttribute("href"));
return false;
}
}
}
}
虽然只是一条if语句,但它可以确保那些“古老”的浏览器不会因为我的脚本代码而出问题。这么做是为了让脚本有良好的向后兼容性。
浏览器嗅探技术
在Javascript脚本代码里,在使用某个特定的方法或属性之前,先测试它是否真实存在是确保向后兼容性最安全和最可信的方法,但它并不是唯一的方法。在浏览器市场群雄逐鹿的那个年代,一种称为浏览器嗅探的技术曾经非常流行。
“浏览器嗅探”指通过提取浏览器供应商提供的信息来解决向后兼容问题。从理论上讲,可以通过Javascript代码检索关于浏览器品牌和版本的信息,这些信息可以用来改善Javascript脚本代码的向后兼容性,但这是一种风险非常大的技术。
首先,浏览器有时会“撒谎”。因为历史原因,有些浏览器会把自己报告成为另外一种浏览器,还有一些浏览器允许用户任意修改这些信息。
其次,为了适用于多种不同的浏览器,浏览器嗅探脚本会变得越来越复杂。如果想让浏览器嗅探脚本能够跨平台工作,就必须测试所有可能出现的供应商和版本号组合。这是一个无穷尽的任务,测试的组合情况越多,代码就越复杂和冗长。
最后,许多浏览器嗅探脚本在进行这类测试时要求浏览器的版本号必须得到精确的匹配。因此,每当市场上出现新版本时,就不得不修改这些脚本。
令人感到欣慰的是,充满着风险的浏览器嗅探技术正在被更简单也更健壮的对象检测技术所取代。
性能考虑
尽量少访问DOM和尽量减少标记:
不管什么时候,只要是查询DOM中的某些元素,浏览器就会搜索整个DOM树,从中查找可能匹配的元素;
另外,过多不必要的元素只会增加DOM树的规模,进而增加遍历DOM树以查找特定元素的时间。
合并和放置脚本:
把脚本都合并到一个脚本文件中,可以减少加载页面时发送的请求数量。而减少请求数量通常都是在性能优化时首先要考虑的。
把<script>标签放到别的地方并不是问题,但把所有<script>标签放到文档的末尾,</body>标记之前,就可以让页面变得更快。即使这样,在加载脚本时,window对象的load事件依然可以执行对文档进行的各种操作。
压缩脚本:
所谓压缩脚本,指的是把脚本文件中不必要的字节,如空格和注释,统统删除,从而达到“压缩”文件的目的。好在,有很多工具都可以替你来做这件事。有的精简程序甚至会重写你的部分代码,使用更短的变量名,从而减少整体文件大小。精简后的代码虽然不易看懂,却能大幅减少文件大小。多数情况下,你应该有两个版本,一个是工作副本,可以修改代码并添加注释;另一个是精简副本,用于放在站点上。通常,为了与非精简版本区分开,最好在精简副本的文件名中加上min字样。
下面是推荐给读者的几个有代表性的代码压缩工具:
Douglas Crockford 的JSMin
雅虎的YUI Compressor
谷歌的Closure Compiler
<!--
作者:纤锐
出处:http://www.cnblogs.com/beginner2014/p/4163056.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。谢谢合作。
-->
JavaScript DOM 编程艺术(第2版)读书笔记(5)的更多相关文章
- Javascript DOM 编程艺术(第二版)读书笔记——基本语法
Javascript DOM 编程艺术(第二版),英Jeremy Keith.加Jeffrey Sambells著,杨涛.王建桥等译,人民邮电出版社. 学到这的时候,我发现一个问题:学习过程中,相当一 ...
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- 《JavaScript DOM编程艺术(第二版)》读书总结
这本书是一本很基础的书,但对于刚入前端不久的我来说是一本不错的书,收获还是很大的,对一些基础的东西理解得更加透彻了. 1.DOM即document object model的缩写,文档对象模型,Jav ...
- 【读书笔记】读《JavaScript DOM 编程艺术-第2版》
1.DHTML DHTML曾被认为是HTML/XHTML.CSS和JavaScript相结合的产物,就像今天的HTML5那样,但把这些东西真正凝聚在一起的是DOM.如果真的需要来描述这一过程的话,“D ...
- Javascript DOM 编程艺术(第二版)读书笔记——DOM基础
1.DOM是什么 D=document(文档) O=object(对象) M=Model(模型) DOM又称节点树 一些术语: parent(父) child(子) sibling(兄弟) ...
- JavaScript -- JavaScript DOM 编程艺术(第2版)
/* 渐进增强 平稳退化 网页 结构层(structural layer): HTML 表示层(presentation layer): CSS <link rel="styleshe ...
- 《JavaScript DOM 编程艺术 第 2 版》
第 5 章 最佳实践 平稳退化:现在基本所有带交互的网站都使用 Ajax,SAP 也火起来了,平稳退化真是很难实现了(看到第七章发现我之前的观点是错了) 分离 JS 向下兼容 性能考虑 第 6 章 案 ...
- JavaScript DOM编程艺术读后感(1)—— 平稳退化
最近,在读<JavaScript DOM编程艺术(第二版)>这本书,想着将自己的读后感记录下来,作为记忆吧. 其实我并不是最近才刚开始读这本书的,我读了有一段时间了.我是一名web前端开发 ...
- JavaScript DOM编程艺术(第2版)的简单总结
介绍 JavaScript DOM编程艺术(第2版)主要讲述了 JavaScript.DOM 和 HTML5 的基础知识,着重讲述了 DOM 编程,并通过几个实例演示了具有专业水准的网页开发. 下面介 ...
- 《JavaScript Dom 编程艺术》读书笔记-第4章
我的前端入门第一本书是<JavaScript Dom 编程艺术>,网上查找资料发现前端的入门推荐书籍最受好评的就是这本和<JavaScript 高级程序设计>了.之所以先选这本 ...
随机推荐
- iOS如何统计渠道
http://bbs.umeng.com/thread-10-1-1.html https://www.zhihu.com/question/20697933
- centos6关闭ipv6
Install packages for CentOS 6.0 Minimal cat <<EOF>>/etc/modprobe.d/disable_ipv6.conf ali ...
- MySQL数据复制的校验
在5.6之前,管理员只能通过ssl实现检校验5.6中,可以使用CRC32检查和来保证master和slave的数据的完整性.校验信息记录在master的二进制日志中和slave的relay日志中. m ...
- iOS 提交代码出现提示弹出框显示 “A commit message is required to perform this operation.Enter a commit message and try again.“
需要你写一下你确认提交的信息,就是你这次提交上去修改了什么功能,简单描述一下
- SQL 数据库 right join 和left join 的区别
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...
- 数据库 SQL基础
数据库是用来存取数据的. 数据库类型: ACESS(比较小,存储少) SQL SERVER (.net) MySQL Oracle(java) 数据库:服务.界面 服务是可以操作的后台的程序. 界面是 ...
- 利用最新版的RubyMine2016.2开发Ruby On Rails 程序
经过我的前两篇博文 ”Ruby On Rails环境搭建“ 和”Ruby On Rails 环境搭建MySQL数据库连接“ 我们已经具备了开发Ruby On Rails程序的一切要素,但是天天对着do ...
- Java基础(38):Calendar类的应用(优于Date类)
Calendar 类的应用 Date 类最主要的作用就是获得当前时间,同时这个类里面也具有设置时间以及一些其他的功能,但是由于本身设计的问题,这些方法却遭到众多批评,不建议使用,更推荐使用 Calen ...
- 。。。Hibernate中mappedBy属性。。。
今天在学习Hibernate中,感觉这个mappedBy这个注解属性有点小难度.不过理解之后,还是阔以的! 首先,mappedBy这个注解只能够用在@OntToOne,@OneToMany,@many ...
- WCF和Web Service的 区(guan)别(xi)
参考文献:http://social.microsoft.com/Forums/zh-CN/c06420d1-69ba-4aa6-abe5-242e3213b68f/wcf-webservice 之前 ...