前言: 笔者平时看过不少前端相关的书, 但由于每本书籍都包含着诸多精彩之处, 所以经常在看完书过一段时间后就或多或少地忘记一些学过的内容故此, 为了探索更高效的学习方法, 笔者准备在每看完一本书后梳理知识框架, 以便日后复习和查证
JavaScript DOM 编程艺术
看书名 Javascript DOM 编程艺术便可得知, 这本书主要介绍了 JavaScript 和 DOM 的一些基础知识和使用方法, 除此之外本书最让人称赞的便是深入浅出地展示了渐进增强平稳退化结构和样式分离等编程思想看完书后, 笔者觉得这本书的教学案例比较基础适合新人学习, 但是书中所提及的很多编程思想却适合低中级层次的前端开发者学习
一 目录结构简述
全书共有 12 章节
前 3 章: 介绍了 JS 简史 JS 语法和 DOM 基础知识
第 4 到 8 章: 通过教学案例来练习扩充 JS 和 DOM 知识, 这 5 章提及了全书的核心编程思想
第 9 章: 介绍了 CSS-DOM
第 10 章: JS 实现动画效果的教学
第 11 章: html5 的介绍
第 12 章: 综合实例练习
二 书中重要知识点梳理
1.JS 中的对象分类:
JS 中的对象分类
2. 节点 (node) 分类:
节点分类
3.DOM 的 5 个重要方法:
DOM 的 5 个重要方法
4.DOM 重要的部分属性:
DOM 重要的部分属性
5.DOM 动态创建标记的方法:
DOM 重要的部分方法
6.JavaScript 编写动画的函数:
JavaScript 的部分函数
三 书中核心编程思想
1. 平稳退化
前端开发者需正确地使用 JS 脚本, 可以让访问者在他们的浏览器不支持 JavaScript 的情况下顺利地浏览你的网站这就是平稳退化, 就是说, 虽然某些功能无法使用, 但是最基本的操作仍可以顺利完成
(1)为了完成平稳退化, 开发者要尽量避免 javascript: 伪协议的使用举个例子, 我们准备通过 "javascript:" 伪协议调用 popUp()函数:
<a href="javascript:popUp('http://www.example.com/');">Example</a>
这条语句在支持伪协议的浏览器中运行正常, 但较老的浏览器尝试打开链接就会失败, 支持伪协议但禁用 JavaScript 功能的浏览器会什么也不做
(2)为了完成平稳退化, 开发者应尽量避免在语句中内嵌事件处理函数如:
<a href="# onclick="poUp('http://www.example.com/'); return false;">Example</a>
上面的 HTML 语句使用了 return false 语句, 这个链接不会真的被打开把 href 属性的值设置为 #只是为了创建空链接实际工作由 onclick 属性负责完成
但是, 这个技巧不支持平稳退化, 如果用户禁用了浏览器的 JavaScript 功能, 这样的链接会毫无用处
(3)为什么要支持平稳退化? 谁关心这个?
不得不说, 如今绝大部分的用户使用的浏览器都支持 JavaScript, 但是如果访问用户是搜索机器人 (searchbot) 搜索机器人是一种自动化的程序, 它们浏览 web 的目的是为了把各种网页添加到搜索引擎的数据库里各大搜索引擎都有类似程序目前, 只有极少的搜索机器人理解 JavaScript 代码所以不支持平稳退化的网页, 它们在搜索引擎上的排名就可能大受损害, 也就是不利于 SEO
根据上面的例子, 我们如何具体到 popUp()函数做到平稳退化? 下面的语句给出了答案:
<a href="http://www.example.com" onclick="popUp(this.href); return false;">Example</a>
这条语句的精髓在于, 对于支持 js 的用户浏览器, 语句通过 return false 禁止了用户点击链接的默认行为, 也就是说点击链接后页面不会跳转对于不支持 js 的用户浏览器, 由于事件处理函数 onclick 失效, 链接可以正常跳转
个人反思:
不得不说, 如今开发的 web 应用越来复杂, 需求越来越多如果想保证所有页面都实现平稳退化对我个人而言有些不现实虽然实现平稳退化利于 SEO 并可以保证极少数使用老旧浏览器的用户顺利访问网站, 但开发者的成本无疑大大增加
不过, 平稳退化仍是一种很好的编程思想, 如果熟练掌握平稳退化的思想, 无疑会在写出更健壮的 web 应用
2. 结构与样式分离和 JavaScript 分离
目前网页是由以下三层信息构成的共同体:
网页的组成
我们都遇见过每个元素都带有 style 属性的文档, 但是这种做法不利于开发人员后期维护和阅读
为了解决这种问题我们应该将样式全部转移到外部文件
同理, 在元素标签内些写 JS 代码也是一种不好的习惯, 如上文中的例子:
<a href="http://www.example.com" onclick="popUp(this.href); return false;">Example</a>
此 a 标签内包含了事件处理函数 onclick, 相对而言, 我们还有一种更好的做法:
- <a href="http://www.example.com" id="getpopUp">Example</a>
- <script>
- var getpopUp=document.getElementById('getpopUp');
- getpopUp.onclick=function(){
- popUp(this.getAttribute('href'));
- return false;
- }
- </script>
这里通过在元素设置挂钩的方式, 使得结构层与行为层分离, 开发者可以更清晰地专注于结构层与行为层的编程
3. 渐进增强
作者说: 标记良好的内容就是一切内容是网站的根本, 在给内容加上各种标记后, 就可以使用各种 CSS 指令控制内容的显示效果了表示层像一张透明的彩色薄膜, 可以包裹在文档的结构上, 使文档内容呈现各种色彩但即使去掉这个表示层, 文档的内容依然能访问行为层的应用方式也和表示层一样
简单来说, 去掉样式层和行为层的包裹, 内容依然能正确的展示给访问者
举个例子, 为了达到最佳表示效果, 应该把 CSS 代码从 HTML 文档中分离出来放在外部文件里
4. 向后兼容
访问你网站的访问者可能未启用 JavaScript, 此外, 有些古老的浏览器很可能不理解 DOM 提供的方法和属性因此, 即使某位用户在访问你的网站时使用的是支持 JavaScript 的浏览器, 某些脚本也不一定能正常工作
针对这一问题的最简单的解决办法是, 检测浏览器对 JavaScript 的支持程度
这个解决办法很容易实现, 只要在某个方法打包在一个 if 语句里, 就可以根据这条 if 语句的条件表达式求值 true(方法存在)或者 false(方法不存在)来决定采用怎样的行动这种检测手段称为对象检测(object detection)
举个例子:
- function myFunction(){
- if( !getElementById || !getElementsByTagName ) return false;
- }
5. 性能考虑
(1)尽量少访问 DOM 和尽量减少标记
访问 DOM 的方式会对脚本的性能产生巨大影响, 每当浏览器查询 DOM 中的某个元素时都会搜索整个 DOM 树因此可以减少函数重复做一件事的情况, 可以将一些值存入全局变量内, 以此提高脚本性能
(2)合并和放置脚本
将逻辑简单的脚本合并到一个脚本文件中, 经验证明, 请求一个大文件的时间比请求多个小文件的时间要短很多
此外, 一般将 < script > 标签放在 </body > 前, 位于 < head > 块中的脚本会导致浏览器无法并行加载其他文件(如图像或其他脚本) 一般来说, 根据 HTT 规范, 浏览器每次只能从同一域名最多只能同时下载两个文件而在下载脚本期间, 浏览器不会下载其他文件, 即使是不同域名的文件也不会下载, 所有其他资源必须等脚本加载完毕后才能下载
(3)压缩脚本
将开发版的脚本压缩成为生产版, 在压缩的途中会去掉不必要的字节, 如空格和注释
推荐压缩工具: Douglas Crockford 的 JSMin 雅虎的 YUI Compressor 和谷歌的 Closure Compiler
6. 对函数进行抽象
有经验的开发者在编程时会对有复用潜力的函数进行抽象, 经过抽象的函数可以变得更加通用把一个非常具体的东西改进为一个较为通用的东西的过程叫做抽象(abstraction)
为了便于理解这个概念, 我们举例说明:
抽象前:
- function styleHeader(){
- if(!document.getElementsByTagName) return false;
- var headers=document.getElementsByTagName("h1");
- headers[1].setAttribute('title','test');
- }
抽象后:
- function styleHeader(tag,setContent){
- if(!document.getElementsByTagName) return false;
- var headers=document.getElementsByTagName(tag);
- headers[1].setAttribute('title',setContent);
- }
7. 组建自己的函数库
我们在开发 web 应用的过程中经常会编写可复用的函数, 因此我们可以将这些可复用的函数积累下来, 组建自己的函数库这类函数应当满足通用性和平稳退化的特点下面我们举例说明:
很多函数需要满足在 HTML 文档完成加载之后执行, 否则 DOM 是不完整的, 函数会加载失败
网页在加载完毕时会触发一个 onload 事件, 这个事件与 window 对象相关联为了完美解决这个问题我们可以封装一个函数:
- function addLoadEvent(func){
- var oldonload=window.onload;
- if( typeof window.onload != 'function'){
- window.onload=func;
- }else{
- window.omload=function(){
- oldonload();
- func();
- }
- }
- }
这个函数非常的实用, 尤其在代码变得很复杂的时候无论打算在页面加载完毕时执行多少个函数, 只要多写一条调用语句就好
四 总结
本书只是向读者展示了通过少数 DOM 方法所能实现的少数功能, 但是书中提及编程思想却是值得笔者思考和探索的精华
因为书中介绍的知识点比较基础, 所以笔者没有详细地归纳总结基础知识点, 本文的重点是对书中作者提及的编程思想进行思考和梳理若文章有不足之处, 望大家批评指正!
来源: http://www.jianshu.com/p/af140806eb3b