Web 前端开发修炼之道


绪 论 1 经济管理类专业规划教材·经济学系列 编写高质量代码 —Web 前端开发修炼之道 曹刘阳 著 李 恒 贾 文 副 主编 计量经济学及其应用 2 本书以网站重构为楔子,深刻而直接地指出了 Web 前端开发中存在的重要问题—代码难 以维护。如何才能提高代码的可维护性?人是最关键的因素!于是本书紧接着全方位地解析了作 为一名合格的前端开发工程师应该掌握的技能和承担的职责,这对刚加入前端开发这一行的读者 来说有很大的指导意义。同时,还解读了制定规范和团队合作的重要性。 本书的核心内容是围绕 Web 前端开发的三大技术要素——HTML、CSS 和 JavaScript 来深入地 探讨编写高质量的 HTML 代码、CSS 代码和 JavaScript 代码的方法、技巧、规范和最佳实践,从而 为编写易于维护的 Web 前端代码打下坚实的基础。这不是一本单纯的“技术”书籍,没有系统地 讲解 Web 前端开发的基础知识,它更专注于“技巧”,探索如何为“技术”提供最佳“技巧”。 本书包含了大量的开发思想和原则,都是作者在长期开发实践中积累下来的经验和心得,不 同水平的 Web 前端开发者都会从中获得启发。尤其是对于那些中初级水平的读者而言,本书是一 本不可多得的内功修炼秘籍。 封底无防伪标均为盗版 版权所有,侵权必究 本书法律顾问 北京市展达律师事务所 图书在版编目(CIP)数据 编写高质量代码:Web 前端开发修炼之道/曹刘阳著. —北京:机械工业出版社,2010.5 ISBN 978-7-111-30595-8 Ⅰ.编… Ⅱ.曹… Ⅲ.主页制作-代码-程序设计 Ⅳ.TP393.092 中国版本图书馆 CIP 数据核字(2010)第 082612 号 机械工业出版社(北京市西城区百万庄大街 22 号 邮政编码 100037) 责任编辑:陈佳媛 版式设计:刘永青 印刷 2010 年 6 月第 1 版第 1 次印刷 186mm×240mm·18.75 印张(含 2.5 印张彩插) 标准书号:ISBN 978-7-111-30595-8 定价:49.00 元 凡购本书,如有缺页、倒页、脱页,由本社发行部调换 客服热线:(010)88378991;88361066 购书热线:(010)68326294;88379649;68995259 投稿热线:(010)88379604 读者信箱:hzjsj@hzbook.com 第 1 章 Eviews软件简介与数据处理方法 III F o r e w o r d 推 荐 序 Web 前端开发是从网页制作演变而来的,名称上有很明显的时代特征。在互联网 的演化进程中,网页制作是 Web 1.0 时代的产物,那时网站的主要内容都是静态的, 用户使用网站的行为也以浏览为主。2005 年以后,互联网进入 Web 2.0 时代,各种类 似桌面软件的 Web 应用大量涌现,网站的前端由此发生了翻天覆地的变化。网页不再 只是承载单一的文字和图片,各种富媒体让网页的内容更加生动,网页上软件化的交 互形式为用户提供了更好的使用体验,这些都是基于前端技术实现的。 以前会 Photoshop 和 Dreamweaver 就可以制作网页,现在只掌握这些已经远远不 够了。无论是开发难度上,还是开发方式上,现在的网页制作都更接近传统的网站后 台开发,所以现在不再叫网页制作,而是叫 Web 前端开发。Web 前端开发在产品开发 环节中的作用变得越来越重要,而且需要专业的前端工程师才能做好,这方面的专业 人才近两年来备受青睐。Web 前端开发是一项很特殊的工作,涵盖的知识面非常广, 既有具体的技术,又有抽象的理念。简单地说,它的主要职能就是把网站的界面更好 地呈现给用户。 如何才能做得更好呢? 第一,必须掌握基本的 Web 前端开发技术,其中包括:CSS、HTML、DOM、 BOM、Ajax、JavaScript 等,在掌握这些技术的同时,还要清楚地了解它们在不同浏览 器上的兼容情况、渲染原理和存在的 Bug。 第二,在一名合格的前端工程师的知识结构中,网站性能优化、SEO 和服务器端 计量经济学及其应用 IV 的基础知识也是必须掌握的。 第三,必须学会运用各种工具进行辅助开发。 第四,除了要掌握技术层面的知识,还要掌握理论层面的知识,包括代码的可维 护性、组件的易用性、分层语义模板和浏览器分级支持,等等。 可见,看似简单的网页制作,如果要做得更好、更专业,真的是不简单。这就是 前端开发的特点,也是让很多人困惑的原因。如此繁杂的知识体系让新手学习起来无 从下手,对于老手来说,也时常不知道下一步该学什么。 目前市面上关于 Web 前端开发的书主要都是针对单一技术的,本书与这些书有着 本质的区别。它主要想实现两个目标:第一,为不太有经验的 Web 前端开发工程师建 立大局观,让他们真正了解和理解这个职业;第二,帮助有一定 Web 前端开发经验的 工程师修炼内功,通过编写高质量的代码来提高前端代码的可维护性。这是很多前端 开发工程师感兴趣的内容。 本书的前两章讨论了网站重构和团队合作,这是很有必要的。网站重构的目的仅 仅是为了让网页更符合 Web 标准吗?不是!重构的本质应该是构建一个前端灵活的 MVC 框架,即 HTML 作为信息模型(Model),CSS 控制样式(View),JavaScript 负 责调度数据和实现某种展现逻辑(Controller)。同时,代码需要具有很好的复用性和可 维护性。这是高效率、高质量开发以及协作开发的基础。建立了这种大局观后,学习 具体技术的思路就更清晰了。 代码质量是前端开发中应该重点考虑的问题之一。例如,实现一个网站界面可能 会有无数种方案,但有些方案的维护成本会比较高,有些方案会存在性能问题,而有 些方案则更易于维护,而且性能也比较好。这里的关键影响因素就是代码质量。 CSS、HTML、JavaScript 这三种前端开发语言的特点是不同的,对代码质量的要求也 不同,但它们之间又有着千丝万缕的联系。本书中包含着很多开发的思想和经验,都 是在长期的开发实践中积累下来的,不同水平的 Web 前端工程师都会从中获得启发。 张克军(著名 Web 前端开发工程师) 2010 年 4 月 P r a i s e 赞 誉 这是一本能修炼前端开发人员内功的书,没有过多的名词解释和理论讲述,都是来 自实战中的经验。本书强调的团队合作和开发习惯对于每一个前端开发团队来说都非常 重要,尤其是大公司的前端开发团队,所有成员都应该了解一下这些内容。对于所有前 端开发人员而言,本书是不可或缺的参考书。 —马波 百度前端开发组项目经理 组织前端技术交流活动是作者最大的喜好之一,对前端技术痴迷,乐于分享。本书 由浅入深地讲解了开发高质量的、易于维护的 Web 前端应用的技巧和注意事项。是辅助 初级 Web 前端开发者进阶的一本好书,强烈推荐。 —赵立元 新浪产品部前端开发技术经理 前端开发工程师是一个易学难精的职业,很多企业常常抱怨招聘不到合适的人才。 市面上此类书籍质量参差不齐,要么是泛泛而谈的理论知识,要么是用大量简单的代码 示例和插图充数。本书的作者是一位有着丰富经验的资深前端开发工程师,无论是他的 理论功底,还是实战经验,你都能在本书中有所体会。本书适合于中初级前端开发工程 师、技术经理和项目经理阅读,选择此书一定不会让你失望。 —罗金 网易的前端开发项目经理 对于经验不太丰富的 Web 前端开发者而言,本书可谓不可多得。书中丰富的编写高 质量前端代码的技巧是在大量实践和总结中结出的硕果,极具学习和参考价值。 —周裕波 百度前端研发工程师、Web 标准化交流会发起人之一 计量经济学及其应用 VI 如今的 Web 应用正朝着规模化和复杂化的方向发展,应用的可维护性变得越来越重 要。本书从编写高质量代码的角度探讨了如何提高 Web 前端代码的可维护性,包含大量 难得的编程技巧,值得学习和研究。 —Ajax 中国(www.okajax.com) 有经验的 Web 前端开发工程师都知道,如果要精通这一行,必须先“精通”十行。 在 Web 前端开发工程师近乎庞杂的知识体系中,HTML、CSS、JavaScript 这三大技术是 最基本的,也是最核心的。本书没有系统地介绍这三个方面的基础知识,重点是讲解了 大量编写高质量 HTML、CSS 和 JavaScript 代码的技巧,旨在提高中初级开发者的水平。 —jQuery 中文社区(http://bbs.jquery.org.cn) 如果你只是初窥 Web 前端开发的门径,强烈建议你阅读本书,它能帮助你修炼内 功。它不仅从知识体系的角度为准备从事 Web 前端开发工作的朋友指明了学习方向,而 且还从技术的角度给出了大量的技巧和最佳实践。 —一起 Ext(http://www.17ext.com/) HTML、CSS、JavaScript 是 Web 前端开发者必须精通的三把利器,本书是关于这三 把利器的使用秘籍,如能善加利用,必定例无虚发。强烈推荐! —CSS 中文社区 P r e f a c e 前 言 前端开发工程师是一个很新的职业,在国内乃至国际上真正开始受到重视的时间不 超过 5 年。但是,随着 Web 2.0 概念的普及和 W3C 组织的推广,网站重构的影响力正以 惊人的速度增长。XHTML+CSS 布局、DHTML 和 Ajax 像一阵旋风,铺天盖地席卷而 来,包括新浪、搜狐、网易、腾讯、淘宝等在内的各种规模的 IT 企业都对自己的网站进 行了重构。 为什么它们会对自己的网站进行重构呢?有两个方面的原因: 第一,根据 W3C 标准进行重构后,可以让前端的代码组织更有序,显著改善网站的 性能,还能提高可维护性,对搜索引擎也更友好; 第二,重构后的网站能带来更好的用户体验,用 XHTML+CSS 重新布局后的页面, 文件更小,下载速度更快。 DHTML 可以让用户的操作更炫,更吸引眼球;Ajax 可以实现无刷新的数据交换, 让用户的操作更流畅。对于普通用户来说,一个网站是否专业、功能是否强大,服务器 端是用 J2EE+Oracle 的强大组合,还是用 ASP+Access 的简单组合,并没有太明显的区 别。但是,前端的用户体验却给了用户直观的印象。 随着人们对用户体验的要求越来越高,前端开发的技术难度越来越大,前端开发工 程师这一职业终于从设计和制作不分的局面中独立出来。前端开发技术包括三个要素: HTML、CSS 和 JavaScript,但随着 RIA 的流行和普及,Flash/Flex、Silverlight、XML 和 服务器端语言也是前端开发工程师应该掌握的。前端开发工程师既要与上游的交互设计 计量经济学及其应用 VIII 师、视觉设计师和产品经理沟通,又要与下游的服务器端工程师沟通,需要掌握的技能 非常多。这就从知识的广度上对前端开发工程师提出了要求。如果要精于前端开发这一 行,也许要先精十行。然而,全才总是少有的。所以,对于不太重要的知识,我们只需 要“通”即可。但“通”到什么程度才算够用呢?对于很多初级前端开发工程师来说, 这个问题是非常令人迷惑的。 前端开发的门槛其实非常低,与服务器端语言先慢后快的学习曲线相比,前端开发 的学习曲线是先快后慢。所以,对于从事 IT 工作的人来说,前端开发是个不错的切入 点。也正因为如此,前端开发领域有很多自学成“才”的同行,但大多数人都停留在会 用的阶段,因为后面的学习曲线越来越陡峭,每前进一步都很难。另一方面,正如前面 所说,前端开发是个非常新的职业,对一些规范和最佳实践的研究都处于探索阶段。总 有新的灵感和技术不时闪现出来,例如 CSS sprite、负边距布局、栅格布局等;各种 JavaScript 框架层出不穷,为整个前端开发领域注入了巨大的活力;浏览器大战也越来越 白热化,跨浏览器兼容方案依然是五花八门。为了满足“高可维护性”的需要,我们需 要更深入、更系统地去掌握前端知识,这样才可能创建一个好的前端架构,保证代码的 质量。 一位好的前端开发工程师在知识体系上既要有广度,又要有深度,所以很多大 公司即使出高薪也很难招聘到理想的前端开发工程师。市面上有很多关于前端开发 的书,这些书籍能很好地指导读者掌握前端开发的基础知识,能让读者达到会用的 水平。然而,几乎还没有书能告诉开发者们如何才能用得更好,如何才能编写出高 质量的前端代码,如何才能系统有效地组织前端架构……本书弥补了这方面的市场 空白,它假定读者已经具有一定的 Web 前端开发基础,不会对基础知识进行详细 介绍,主要精力放在如何编写和组织高质量代码上,从而提高代码的可维护性。 本书的重点不在于讲解技术,而是更侧重于对技巧的讲解。技术非黑即白,只有对 和错,而技巧则见仁见智。本书是笔者个人的经验分享,尽信书不如无书,大家可以有 选择地吸收,如果对书中的观点或技巧有不同的见解,非常欢迎与笔者讨论交流。大家 可以通过邮箱 cly84920@gmail.com 与作者取得联系,也可以通过 QQ 群 8791223 参与到 “如何编写高质量前端代码”的讨论中来。 第 1 章 Eviews软件简介与数据处理方法 IX 在编写本书的过程中,如何组织目录一直是让笔者非常纠结的事情:HTML、CSS 和 JavaScript 是三门截然不同的语言,在实际应用过程中涉及的深度也各不相同,HTML 需注意的事项较少,CSS 次之,JavaScript 最为复杂。所以,本书虽然会同时对这三个方 面进行探讨,但所用篇幅与它们的复杂度是成正比的。 第 1 章 Eviews软件简介与数据处理方法 III 致 谢 A c k n o w l e d g m e n t 感谢在本书写作过程中为我提供宝贵意见的朋友们,他们是周裕波、钟志、刘运 周、李海玲、钟伟明、邹渤一、黄海宝、胡淑芳,没有你们的反馈,这本书将失色不 少。 感谢克军为我写的推荐序,很怀念我们一起吃午饭的那段日子,下次音乐节我一定 到。感谢卢海军为我提供了三张精美的插图,它们真的很漂亮。 感谢华章编辑们的细心工作,谢谢你们一直耐心友好地对待我一次又一次的拖稿, 与你们合作非常愉快。 感谢我的家人,谢谢你们在我最没有耐心写下去的时候一直陪着我。谢谢我的老婆 张霞,没有你每天的督促,真不知道这本书要写到哪天才写得完。 C o n t e n t s 目 录 推荐序 赞 誉 前 言 致 谢 第 1 章 从网站重构说起/1 1.1 糟糕的页面实现,头疼的维护工作/2 1.2 Web 标准—结构、样式和行为的分离/4 1.3 前端的现状/6 1.4 打造高品质的前端代码,提高代码的可维护性—精简、重用、有序/8 第 2 章 团队合作/9 2.1 揭秘前端开发工程师/10 2.2 欲精一行,必先通十行/13 2.3 增加代码可读性—注释/15 2.4 提高重用性—公共组件和私有组件的维护/15 2.5 冗余和精简的矛盾—选择集中还是选择分散/16 2.6 磨刀不误砍柴工—前期的构思很重要/17 计量经济学及其应用 XII 2.7 制订规范/18 2.8 团队合作的最大难度不是技术,是人/18 第 3 章 高质量的 HTML/19 3.1 标签的语义/20 3.2 为什么要使用语义化标签/21 3.3 如何确定你的标签是否语义良好/26 3.4 常见模块你真的很了解吗/36 3.4.1 标题和内容/36 3.4.2 表单/38 3.4.3 表格/40 3.4.4 语义化标签应注意的一些其他问题/43 第 4 章 高质量的 CSS/44 4.1 怪异模式和 DTD/45 4.2 如何组织 CSS/46 4.3 推荐的 base.css/49 4.4 模块化 CSS—在 CSS 中引入面向对象编程思想/55 4.4.1 如何划分模块—单一职责/55 4.4.2 CSS 的命名—命名空间的概念/60 4.4.3 挂多个 class 还是新建 class —多用组合,少用继承/66 4.4.4 如何处理上下 margin/72 4.5 低权重原则—避免滥用子选择器/81 4.6 CSS sprite/85 4.7 CSS 的常见问题/88 4.7.1 CSS 的编码风格/88 d g m 第 1 章 Eviews 软件简介与数据处理方法 XIII 4.7.2 id 和 class/89 4.7.3 CSS hack/89 4.7.4 解决超链接访问后 hover 样式不出现的问题/93 4.7.5 hasLayout/94 4.7.6 块级元素和行内元素的区别/95 4.7.7 display:inline-block 和 hasLayout/97 4.7.8 relative、absolute 和 float/103 4.7.9 居中/104 4.7.10 网格布局/112 4.7.11 z-index 的相关问题以及 Flash 和 IE 6 下的 select 元素/122 4.7.12 插入 png 图片/129 4.7.13 多版本 IE 并存方案—CSS 的调试利器 IETester/131 第 5 章 高质量的 JavaScript/133 5.1 养成良好的编程习惯/134 5.1.1 团队合作—如何避免 JS 冲突/134 5.1.2 给程序一个统一的入口—window.onload 和 DOMReady/148 5.1.3 CSS 放在页头,JavaScript 放在页尾/159 5.1.4 引入编译的概念—文件压缩/160 5.2 JavaScript 的分层概念和 JavaScript 库/162 5.2.1 JavaScript 如何分层/162 5.2.2 base 层/163 5.2.3 common 层/181 5.2.4 page 层/184 5.2.5 JavaScript 库/185 5.3 编程实用技巧/187 5.3.1 弹性/187 计量经济学及其应用 XIV 5.3.2 getElementById、getElementsByTagName 和 getElements- ByClassName/193 5.3.3 可复用性/196 5.3.4 避免产生副作用/199 5.3.5 通过传参实现定制/203 5.3.6 控制 this 关键字的指向/207 5.3.7 预留回调接口/211 5.3.8 编程中的 DRY 规则/212 5.3.9 用 hash 对象传参/215 5.4 面向对象编程/217 5.4.1 面向过程编程和面向对象编程/217 5.4.2 JavaScript 的面向对象编程/224 5.4.3 用面向对象方式重写代码/245 5.5 其他问题/251 5.5.1 prototype 和内置类/251 5.5.2 标签的自定义属性/255 5.5.3 标签的内联事件和 event 对象/260 5.5.4 利用事件冒泡机制/263 5.5.5 改变 DOM 样式的三种方式/267 附录 A 写在规则前面的话/271 附录 B 命名规则/272 附录 C 分工安排/274 附录 D 注释规则/276 附录 E HTML 规范/278 附录 F CSS 规范/280 附录 G JavaScript 规范/282 第 1 章 从网站重构说起 本章内容 糟糕的页面实现,头疼的维护工作 Web 标准——结构、样式和行为的分离 前端的现状 打造高品质的前端代码,提前代码的可维护性——精简、重用、有序 1.1 糟糕的页面实现,头疼的维护工作 代码清单 1-1 一个糟糕老网页的实现 网址之家--动漫 1.2 Web 标准——结构、样式和行为的分离 代码清单 1-2 结构、样式和行为混杂的网页 下载 代码清单 1-3 结构、样式和行为分别用单独文件分离开 test.html 文件: 下载 ============================================================== test.css 文件: .myTd{width:100%;height:20px;text-align:center;} .myFont{color:#346F0E;} #myInput{margin-bottom:-5px;font-size:16px;height:1.78em;font-family:arial,sans- serif,宋体;padding-top:2px;padding-left:1px} ============================================================== test.js 文件 var myInput = document.getElementById(“myInput”); myInput.onmouseover = function(){ this.focus(); } myInput.onfocus = function(){ this.select(); } 代码清单 1-4 样式和行为在网页内分离开 下载 1.3 前端的现状 1.4 打造高品质的前端代码,提高代码的可维护性——精简、重 用、有序 第 2 章 团队合作 本章内容 揭密前端开发工程师 欲精一行,必选通十行 增加代码可读性——注释 提高重用性——公共组件和私有组件的维护 冗余和精简的矛盾——选择集中还是选择分散 磨刀不误砍柴功——前期的构思很重要 制订规范 团队合作最大的难度不是技术,是人 2.1 揭密前端开发工程师 2.2 欲精一行,必先通十行 2.3 增加代码可读性——注释 2.4 提高重用性——公共组件和私有组件的维护 2.5 冗余和精简的矛盾——选择集中还是选择分散 2.6 磨刀不误砍柴功——前期的构思很重要 2.7 制订规范 2.8 团队合作最大的难度不是技术,是人 第 3 章 高品质的 HTML 本章内容 标签的语义 为什么要使用语义化标签 如何确定你的标签是否语义良好 常见模块详解 3.1 标签的语义 3.2 为什么要使用语义化标签 代码清单 3-1 简单页面 阿当的简单示例

h1 标签

h2 标签

h3 标签

p 标签

div 标签
span 标签 strong 标签
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
代码清单 3-2 简单页面的 CSS 代码 h1{font-size:12px;font-weight:normal;} h2{font-size:16px;} h3{font-size:20px;font-weight:normal;} p{size:normal;background:#333;color:#fff;padding:50px;font-size:30px;font-weight :bold;} div{display:inline;} strong{display:block;padding:10px;border:1px dashed #000;margin:20px 50px;} .text{width:300px;height:100px;} textarea{width:150px;height:20px;border:4px solid #999;background:#ccc;overflow:auto;} .btn{border:3px solid green;background:black;color:#fff;} ul{list-style:none;} li{padding:10px;border:1px dashed #ccc;float:left;margin:0 2px;} 3.3 如何确定你的标签是否语义良好 3.4 常见模块详解 3.4.1 标题和内容 代码清单 3-3 标题和内容模块实现方案一 html 部分:
标签的语义更多>>
段落一的内容。。。根据浏览器的默认样式 。。。
段落二的内容
CSS 部分: .h2{position:relative;border-bottom:1px dashed #fff;} .h2 a{position:absolute;right:0;top:0;} .p{text-indent:2em;line-height:150%;margin:0 0 20px 0;} .strong{color:red;} 代码清单 3-4 标题和内容模块实现方案一的语义 <分隔 class=“h2”>标签的语义<锚点 href=“#”>更多>> <分隔>段落一的内容。。。<范围 class=“strong”>根据浏览器的默认样式 。。。 <分隔>段落二的内容 代码清单 3-5 标题和内容模块实现方案二 html 部分:

标签的语义 更多>>

段落一的内容。。。根据浏览器的默认样式 。。。

段落二的内容

CSS 部分: h2{position:relative;border-bottom:1px dashed #fff;} h2 a{position:absolute;right:0;top:0;} p{text-indent:2em;line-height:150%;margin:0 0 20px 0;} strong{color:red;font-weight:normal} 代码清单 3-6 标题和内容模块实现方案二的语义 <二级标题>标签的语义<锚点 href=“#”>更多>> <段落>段落一的内容。。。<强调>根据浏览器的默认样式 。。。 <段落>段落二的内容 代码清单 3-7 标题和内容模块实现方案三 html 部分:

标签的语义

更多>>

段落一的内容。。。根据浏览器的默认样式 。。。

段落二的内容

CSS 部分: h2{} a{} p{text-indent:2em;line-height:150%;margin:0 0 20px 0;} strong{color:red;font-weight:normal} 代码清单 3-8 标题和内容模块实现方案三的语义 <二级标题>标签的语义 <锚点 href=“#”>更多>> <段落>段落一的内容。。。<强调>根据浏览器的默认样式 。。。 <段落>段落二的内容 代码清单 3-9 标题和内容模块实现方案三的改进版 html 部分:

标签的语义

更多>>

段落一的内容。。。根据浏览器的默认样式 。。。

段落二的内容

CSS 部分: .title{border-bottom:1px dashed #fff;text-align:right;} .title h2{float:left;} p{text-indent:2em;line-height:150%;margin:0 0 20px 0;} strong{color:red;font-weight:normal} 3.4.2 表单 代码清单 3-10 表单模块实现方案一
帐号 :
密码 :
代码清单 3-11 表单模块实现方案一的语义 <表单 action=“” method=“” class=“fieldset”> <分隔><范围>帐号 : <表单项 type="text" id="name" /> <分隔><范围>密码 : <表单项 type=“password” id=“pw” /> <表单项 type="submit" value="登陆" class="subBtn" /> 代码清单 3-12 表单模块实现方案二
登录表单

代码清单 3-13 表单模块实现方案二的语义 <表单 action=“” method=“” class=“fieldset”> <域集> <域集名>登录表单 <段落><表单项说明 for=“name”>帐号 : <表单项 type=“text” id= “name” /> <段落><表单项说明 for=“pw”>密码 : <表单项 type=“password” id= “pw” /> <表单项 type="submit" value="登陆" class="subBtn" /> 代码清单 3-14 表格模块实现方案一
几种页面实现的比较
实现方式代码量搜索引擎友好特殊终端兼容
table 布局一般
乱用标签的 CSS 布局一般
标签语义良好的 CSS 布局
代码清单 3-15 表格模块实现方案一的语义 <分隔 class=“caption”>几种页面实现的比较 <表格 border="1"> <表格行 class="thead"><表格单元格 class="th">实现方式<表格单元格 class="th">代码量<表格单元格 class="th">搜索引擎友好<表格单元格 class="th">特殊终端兼容 <表格行><表格单元格 class="th">table 布局<表格单元格>多<表 格单元格>差<表格单元格>一般 <表格行><表格单元格class="th">乱用标签的CSS布局<表格单元格>少<表格单元格>一般<表格单元格>差 <表格行><表格单元格 class="th">标签语义良好的 CSS 布局<表格单元格>少< 表格单元格>好<表格单元格>好 <分隔><范围>帐号 : <表单项 type="text" id="name" /> <分隔><范围>密码 : <表单项 type=“password” id=“pw” /> <表单项 type="submit" value="登陆" class="subBtn" /> 代码清单 3-16 表格模块实现方案二
几种页面实现的比较
实现方式代码量搜索引擎友好特殊终端兼容
table 布局一般
乱用标签的 CSS 布局一般
标签语义良好的 CSS 布局
代码清单 3-17 表格模块实现方案二的语义 <表格 border="1"> <表格标题>几种页面实现的比较 <表格头部> <表格行> <表头>实现方式<表头>代码量<表头>搜索引擎友好<表 头>特殊终端兼容 <表格主体> <表格行><表头>table 布局<表格单元格>多<表格单元格>差<表格单元格>一般 <表格行><表头>乱用标签的 CSS 布局<表格单元格>少<表格单元格 >一般<表格单元格>差 <表格行><表头>标签语义良好的 CSS 布局<表格单元格>少<表格单 元格>好<表格单元格>好 3.4.4 语义化标签应注意的一些其他问题 第 4 章 高品质的 CSS 本章内容 怪异模式和 DTD 如何组织 CSS 推荐的 base.css 模块化 CSS——引入编程的思想到 CSS 低权重原则——避免滥用子选择器 CSS sprite CSS 的常见问题 4.1 怪异模式和 DTD 代码清单 4-1 HTML 中常见的 4 种 DTD 类型 用于 HTML 4.01 的严格型 用于 HTML 4.01 的过渡型 用于 XHTML 1.0 的严格型 用于 XHTML 1.0 的过渡型 4.2 如何组织 CSS 代码清单 4-2 page.css 的注释 /*首页*/ .test{} .test2{} /*关于我们*/ .test3{} .test4{} /*联系我们*/ .test5{} .test6{} 4.3 推荐的 base.css 代码清单 4-3 base.css .mb5{margin-bottom:5px}/*CSS reset*/ body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p, blockquote,th,td {margin:0;padding:0;} table {border-collapse:collapse;border-spacing:0;} fieldset,img {border:0} address,caption,cite,code,dfn,em,strong,th,var {font-style:normal;font-weight:normal} ol,ul {list-style:none} caption,th {text-align:left} h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} q:before,q:after {content:''} abbr,acronym { border:0} /*文字排版*/ .f12{font-size:12px} .f13{font-size:13px} .f14{font-size:14px} .f16{font-size:16px} .f20{font-size:20px} .fb{font-weight:bold} .fn{font-weight:normal} .t2{text-indent:2em} .lh150{line-height:150%} .lh180{line-height:180%} .lh200{line-height:200%} .unl{text-decoration:underline;} .no_unl{text-decoration:none;} /*定位*/ .tl{text-align:left} .tc{text-align:center} .tr{text-align:right} .bc{margin-left:auto;margin-right:auto;} .fl{float:left;display:inline} .fr{float:right;display:inline} .cb{clear:both} .cl{clear:left} .cr{clear:right} .clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden} .clearfix{display:inline-block}* html .clearfix{height:1%}.clearfix{display:block} .vm{vertical-align:middle} .pr{position:relative} .pa{position:absolute} .abs-right{position:absolute;right:0} .zoom{zoom:1} .hidden{visibility:hidden} .none{display:none} /*长度高度*/ .w10{width:10px} .w20{width:20px} .w30{width:30px} .w40{width:40px} .w50{width:50px} .w60{width:60px} .w70{width:70px} .w80{width:80px} .w90{width:90px} .w100{width:100px} .w200{width:200px} .w250{width:250px} .w300{width:300px} .w400{width:400px} .w500{width:500px} .w600{width:600px} .w700{width:700px} .w800{width:800px} .w{width:100%} .h50{height:50px} .h80{height:80px} .h100{height:100px} .h200{height:200px} .h{height:100%} /*边距*/ .m10{margin:10px} .m15{margin:15px} .m30{margin:30px} .mt5{margin-top:5px} .mt10{margin-top:10px} .mt15{margin-top:15px} .mt20{margin-top:20px} .mt30{margin-top:30px} .mt50{margin-top:50px} .mt100{margin-top:100px} .mb10{margin-bottom:10px} .mb15{margin-bottom:15px} .mb20{margin-bottom:20px} .mb30{margin-bottom:30px} .mb50{margin-bottom:50px} .mb100{margin-bottom:100px} .ml5{margin-left:5px} .ml10{margin-left:10px} .ml15{margin-left:15px} .ml20{margin-left:20px} .ml30{margin-left:30px} .ml50{margin-left:50px} .ml100{margin-left:100px} .mr5{margin-right:5px} .mr10{margin-right:10px} .mr15{margin-right:15px} .mr20{margin-right:20px} .mr30{margin-right:30px} .mr50{margin-right:50px} .mr100{margin-right:100px} .p10{padding:10px;} .p15{padding:15px;} .p30{padding:30px;} .pt5{padding-top:5px} .pt10{padding-top:10px} .pt15{padding-top:15px} .pt20{padding-top:20px} .pt30{padding-top:30px} .pt50{padding-top:50px} .pb5{padding-bottom:5px} .pb10{padding-bottom:10px} .pb15{padding-bottom:15px} .pb20{padding-bottom:20px} .pb30{padding-bottom:30px} .pb50{padding-bottom:50px} .pb100{padding-bottom:100px} .pl5{padding-left:5px} .pl10{padding-left:10px} .pl15{padding-left:15px} .pl20{padding-left:20px} .pl30{padding-left:30px} .pl50{padding-left:50px} .pl100{padding-left:100px} .pr5{padding-right:5px} .pr10{padding-right:10px} .pr15{padding-right:15px} .pr20{padding-right:20px} .pr30{padding-right:30px} .pr50{padding-right:50px} .pr100{padding-right:100px} 4.4 模块化 CSS —— 引入面向对象的编程思想到 CSS 4.4.1 如何划分模块 —— 单一职责 4.4.2 CSS 的命名 —— 命名空间的概念 代码清单 4-4 css 命名方案一
  • 2009 年 08 月(3)
  • 2009 年 07 月(12)
  • 2009 年 06 月(3)
  • 2009 年 05 月(8)
  • 2009 年 04 月(2)
  • 2009 年 03 月(8)
代码清单 4-5 css 命名方案二
  • 2009 年 08 月(3)
  • 2009 年 07 月(12)
  • 2009 年 06 月(3)
  • 2009 年 05 月(8)
  • 2009 年 04 月(2)
  • 2009 年 03 月(8)
代码清单 4-6 css 命名方案三
  • 2009 年 08 月(3)
  • 2009 年 07 月(12)
  • 2009 年 06 月(3)
  • 2009 年 05 月(8)
  • 2009 年 04 月(2)
  • 2009 年 03 月(8)
代码清单 4-7 css 命名冲突
  • 2009 年 08 月(3)
  • 2009 年 07 月(12)
  • 2009 年 06 月(3)
  • 2009 年 05 月(8)
  • 2009 年 04 月(2)
  • 2009 年 03 月(8)
...
  1. 2009-08-07
  2. 2009-08-06
  3. 2009-08-05
代码清单 4-8 css 命名加前辍
  • 2009 年 08 月(3)
  • 2009 年 07 月(12)
  • 2009 年 06 月(3)
  • 2009 年 05 月(8)
  • 2009 年 04 月(2)
  • 2009 年 03 月(8)
...
  1. 2009-08-07
  2. 2009-08-06
  3. 2009-08-05
代码清单 4-9 不加前辍的命名方式
代码清单 4-10 加前辍的命名方式
4.4.3 挂多个 class 还是新建 class ——多用组合,少用继承 代码清单 4-11 三个简单模块实现方案一 代码清单 4-12 三个简单模块实现方案二 代码清单 4-13 三个简单模块实现方案三 代码清单 4-14 方案二面对扩展 代码清单 4-15 方案三面对扩展 代码清单 4-16 YUI3 中的 class
Overlay Header Content
Overlay Body Content
Overlay Footer Content
4.4.4 如何处理上下 margin 代码清单 4-17 提取标题组件

服务理念

服务宗旨

Gsns 产品的优势

… 代码清单 4-18 包含 margin 的标题组件

服务理念

服务宗旨

Gsns 产品的优势

… 代码清单 4-19 应用类的组合

服务理念

服务宗旨

Gsns 产品的优势

… 4.5 低权重原则 —— 避免滥用子选择器 代码清单 4-20 css 的层叠 1234567890 代码清单 4-21 css 层叠有冲突的情况 1234567890 代码清单 4-22 选择符权重相同的情况 1234567890 代码清单 4-23 调换样式的位置 1234567890 代码清单 4-24 需标红的代码

CSS 选择符权重很重要

代码清单 4-25 用子选择器

CSS 选择符权重很重要

代码清单 4-26 新建 class

CSS 选择符权重很重要

代码清单 4-27 添加新的文本

CSS 选择符权重很重要,我们要小心处理

代码清单 4-28 需标绿的代码

CSS 选择符权重很重要,我们要小心处理

代码清单 4-29 被迫加重权重的选择器

CSS 选择符权重很重要,我们要小心处理

代码清单 4-30 新增 class 作为标绿容器的选择符

CSS 选择符权重很重要,我们要 小心处理

4.6 CSS sprite 代码清单 4-31 用两张图实现高亮 代码清单 4-32 利用一张大图的背景移动实现高亮 4.7 CSS 的常见问题 4.7.1 CSS 的编码风格 代码清单 4-33 多行式的 css 编码风格 .test{ width:100px; height:50px; color:#ccc; } .demo{ background-color:green; font-size:20px; } 代码清单 4-34 一行式的 css 编码风格 .test{width:100px;height:50px; color:#ccc;} .demo{background-color:green;font-size:20px;} 4.7.2 id 和 class 4.7.3 CSS hack 代码清单 4-35 只在 IE 下生效 代码清单 4-36 只在 IE6 下生效 代码清单 4-37 只在 IE6 以上版本生效 代码清单 4-38 只在 IE7 上不生效 代码清单 4-39 条件注释和 style 标签 代码清单 4-40 条件注释和 script 标签 代码清单 4-41 ie6.css、ie7.css 和 ie8.css 1) ie6.css .test{width:60px;} 2) ie7.css .test{width:70px;} 3) IE 8.css .test{width:80px;} 代码清单 4-42 针对不同 IE 版本分别导入样式 代码清单 4-43 选择符前辍 hack 法 代码清单 4-44 样式属性前辍 hack 法 4.7.4 超链接访问过后 hover 样式就不出现的问题 代码清单 4-45 不正确的伪类顺序 hello world 代码清单 4-46 正确的伪类顺序 hello world 4.7.5 hasLayout 4.7.6 块级元素和行内元素的区别 代码清单 4-47 块级元素和行内元素

块级元素 p

块级元素 div
行内元素 span行内元素 strong 代码清单 4-48 对块级元素和行内元素设置长宽

块级元素 p

块级元素 div
行内元素 span行内元素 strong 代码清单 4-49 块级元素、行内元素的 margin 和 padding

块级元素 p

块级元素 div
行内元素 span行内元素 strong 代码清单 4-50 改变块级元素和行内元素的显示

块级元素 p

块级元素 div
行内元素 span行内元素 strong 4.7.7 display:inline-block 和 hasLayout 代码清单 4-51 设置 display:inline-block abcdefg

12345

代码清单 4-52 触发 hasLayout 在 IE6、IE7 下模拟 inline-block abcdefg 12345 代码清单 4-53 调整竖直排列的位置 abcdefg 12345 4.7.8 relative、absolute 和 float 4.7.9 居中 代码清单 4-54 行内元素的水平居中
hello world
代码清单 4-55 确定宽度的块级元素的水平居中
代码清单 4-56 不确定宽度的块级元素的水平居中方法一
代码清单 4-57 不确定宽度的块级元素的水平居中方法二
代码清单 4-58 不确定宽度的块级元素的水平居中方法三
代码清单 4-59 父元素高度不确定的文本、图片、块级元素的竖直居中
hello world
代码清单 4-60 父元素高度确定的单行文本的竖直居中
hello world
代码清单 4-61 父元素高度确定的多行文本、图片、块级元素的竖直居中方法一
hello world
hello world
hello world
代码清单 4-62 父元素高度确定的多行文本、图片、块级元素的竖直居中方法二
hello world
hello world
hello world
4.7.10 网格布局 代码清单 4-63 两栏式布局方案一
代码清单 4-64 两栏式布局方案二
代码清单 4-65 调换左右两栏的位置
代码清单 4-66 用类的组合的方式设定浮动方向
代码清单 4-67 用类的组合的方式面对简单修改
代码清单 4-68 用类的组合的方式面对复杂修改
代码清单 4-69 将宽度提取出来
代码清单 4-70 用子选择器应对复杂变化
代码清单 4-71 组合类的方式面对扩展
代码清单 4-72 子选择器方式面对扩展
代码清单 4-73 子选择器布局的嵌套使用
4.7.11 z-index 和 Flash、IE 6 下的 select 代码清单 4-74 z-index 设置高低
代码清单 4-75 调整 z-index 的高低
代码清单 4-76 z-index 设为负数
代码清单 4-77 为 one、two、three 监听 click 事件
xxxxxxxxxx
代码清单 5-2 工程师乙添加功能 B
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-3 使用匿名函数控制变量的作用域
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-4 功能 C 和功能 A 的通信
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-5 工程师丙添加功能 C
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-6 利用全局作用域的变量在各匿名函数间搭起桥梁
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-7 添加新的全局变量
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-8 用 hash 对象作为全局变量
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-9 全局变量的冲突
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-10 使用命名空间
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-11 使用多级命名空间
xxxxxxxxxxx
代码清单 5-12 定义命名空间函数
xxxxxxxxxxx
代码清单 5-13 使用命名空间解决冲突的完整代码
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-14 给代码添加注释
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
5.1.2 给程序一个统一的入口——window.onload 和 DOMReady 代码清单 5-15 区分 javascript 的框架部分和应用部分
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-16 给应用部分一个统一的“入口”
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-17 在 DOM 节点加载进来之前就调用
hello world
代码清单 5-18 调整脚本的位置
hello world
代码清单 5-19 监听 window.onload
hello world
代码清单 5-20 定义初始化方法的名称为 init
hello world
代码清单 5-21 jQuery 中监听 DOMReady
hello world
代码清单 5-22 YUI 中监听 DOMReady
hello world
代码清单 5-23 模拟 DOMReady 效果
hello world
代码清单 5-24 调用 init 函数
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-25 框架部分的代码
xxxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
xxxxxxxxxx
代码清单 5-26 头部文件 阿当制作
...
代码清单 5-27 尾部文件
...
代码清单 5-28 主体文件
...
代码清单 5-29 更健壮的 init 调用
...
5.1.3 CSS 放在页头,JavaScript 放在页尾 代码清单 5-30 有 JavaScript 和 CSS 的网页
xxxxx
代码清单 5-31 将 CSS 放在页头,JavaScript 放在页尾
xxxxx
5.1.4 引入编译的概念——文件压缩 代码清单 5-32 未压缩的 JavaScript 脚本 //定义两个字符串 var testStr = "hello"; var testStr2 = "world"; //连接字符串函数 function addStr(str,str2){ return str + " " + str2; } //调用函数,连接定义的两个字符串 addStr(testStr,testStr2); 代码清单 5-33 压缩后的 JavaScript 脚本 var testStr="hello";var testStr2="world";function addStr(a,b){return a+" "+b}addStr(testStr,testStr2); 5.2 JavaScript 的分层概念和 JavaScript 库 5.2.1 JavaScript 如何分层 5.2.2 base 层 代码清单 5-34 简单的代码 代码清单 5-35 查看 IE 和 firefox 下的区别 代码清单 5-36 去掉空格 代码清单 5-37 分别对 IE 和 firefox 写程序 代码清单 5-38 针对 IE 和 firefox 分别写程序如何面对扩展 代码清单 5-39 用 getNextNode 函数封装 IE 和 firefox 的差异 代码清单 5-40 针对 IE 和 firefox 分别设置透明度
代码清单 5-41 封装 setOpacity 函数
代码清单 5-42 点击事件和参数 代码清单 5-43 兼容 IE 和 firefox 的 event 对象 代码清单 5-44 兼容 srcElement 和 target hello world 代码清单 5-45 封装 getEventTarget 函数 hello world 代码清单 5-46 event 对象的冒泡

代码清单 5-47 监测冒泡的过程

代码清单 5-48 阻止事件冒泡

代码清单 5-49 封装 stopPropagation 函数

代码清单 5-50 监听 click 事件 代码清单 5-51 监听两个 click 事件 代码清单 5-52 on xxx 在多人合作时的冲突问题 代码清单 5-53 使用 attachEvent 和 addEventListener 代替 on xxx 代码清单 5-54 封装 on 函数 代码清单 5-55 定义 trim 函数 function trim(ostr){ return ostr.replace(/^\s+|\s+$/g,""); } var str = " abc "; alert(trim(str).length); // 3 alert(" "==""); // false alert(trim(" ") == ""); // true 代码清单 5-56 定义类型判断函数 function isNumber(s){ return !isNaN(s); } function isString(s){ return typeof s == "string"; } function isBoolean(s){ return typeof s == "boolean"; } function isFunction(s){ return typeof s == "function"; } function isNull(s){ return s == null; } function isUndefined(s){ return typeof s == "undefined"; } function isEmpty(s){ return /^\s*$/.test(s); } function isArray(s){ return s instanceof Array; } 代码清单 5-57 定义 get 和$函数 function get(node){ node = typeof node == "string" ? document.getElementById(node) : node; return node; } function $(node){ node = typeof node == "string" ? document.getElementById(node) : node; return node; } alert(get("test1").innerHTML); // Hello alert($("test2").innerHTML) // World 代码清单 5-58 定义 getElementsByClassName 函数 1 2

3

4
5
6
代码清单 5-62 设置 cookie document.cookie = "cookieName = cookieValue; expirationdate = timeValue; path = pathValue"; 代码清单 5-63 读写 cookie // 设置 cookie document.cookie = "name=adang; expires= Mon, 30 Nov 2009 05:49:47 GMT; path=/"; document.cookie = "sex=male; expires= Mon, 30 Nov 2009 05:49:47 GMT; path=/"; document.cookie = "blog=http://www.adanghome.com; expires= Mon, 30 Nov 2009 05:49:47 GMT; path=/"; /* 读取 cookie ** 此时 cookie 里的值为"name=adang; sex=male; blog=http://www.adanghome.com" */ var cookieStr = document.cookie; // 对字符进行操作,取出 name 对应的值 var name = cookieStr.split("name")[1].split(";")[0].split("=")[1]; 代码清单 5-64 封装 cookie 组件 GLOBAL.namespace("Cookie"); GLOBAL.Cookie={ // 读取 read : function(name){ var cookieStr = "; "+document.cookie+"; "; var index = cookieStr.indexOf("; "+name+"="); if (index!=-1){ var s = cookieStr.substring(index+name.length+3,cookieStr.length); return unescape(s.substring(0, s.indexOf("; "))); }else{ return null; } }, // 设置 set : function(name,value,expires){ var expDays = expires*24*60*60*1000; var expDate = new Date(); expDate.setTime(expDate.getTime()+expDays); var expString = expires ? "; expires="+expDate.toGMTString() : ""; var pathString = ";path=/"; document.cookie = name + "=" + escape(value) + expString + pathString; }, // 删除 del : function(name){ var exp = new Date(new Date().getTime()-1); var s=this.read(name); if(s!=null) {document.cookie= name + "="+s+";expires="+exp.toGMTString()+";path=/"}; } }; 代码清单 5-65 引用可拖拽的 Msg 组件 5.2.4 page 层 5.2.5 JavaScript 库 5.3 编程实用技巧 5.3.1 弹性 代码清单 5-66 开始编写 Tab 组件
  • menu1
  • menu2
  • menu3
content1
content2
content3
代码清单 5-67 给 html 标签挂上 id …
  • menu1
  • menu2
  • menu3
content1
代码清单 5-68 提高 Tab 的扩展性 …
  • menu1
  • menu2
  • menu3
  • menu4
content1
content2
content3
content4
代码清单 5-69 循环中的 i for(var i=0;i
  • menu1
  • menu2
content1
content2
代码清单 5-73 五个标签的 Tab
  • menu1
  • menu2
  • menu3
  • menu4
  • menu5
content1
content2
content3
content4
content5
代码清单 5-74 结构稍复杂的 Tab
  • menu1
  • menu2
  • menu3
content1
  • abc

content2

abc
content3
代码清单 5-75 复杂 Tab 结构带来的问题
  • menu1
  • menu2
  • menu3
content1
  • abc

content2

abc
content3
5.3.3 可复用性 代码清单 5-77 将 id 换为 class …
  • menu1
  • menu2
  • menu3
… var tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu"); … 代码清单 5-78 三个 Tab
  • menu1-1
  • menu1-2
  • menu1-3
content1-1
    abc
  • menu2-1
  • menu2-2
content2-1
    abc
  • menu3-1
  • menu3-2
  • menu3-3
  • menu3-4
  • menu3-5
content3-1
    abc
代码清单 5-79 给 Tab 添加根结点挂钩 …
5.3.4 避免产生副作用 代码清单 5-80 高亮当前 Tab
  • menu1-1
  • menu1-2
  • menu1-3
  • menu2-1
  • menu2-2
  • menu3-1
  • menu3-2
  • menu3-3
  • menu3-4
  • menu3-5
代码清单 5-81 修改 className if(currentMenu){ currentMenu.className = ""; } this.className = "tab-currentMenu"; 代码清单 5-82 修改 className 引起的冲突
  • menu1-1
  • menu1-2
  • menu1-3
… 代码清单 5-83 修改至无副作用 if(currentMenu){ currentMenu.className = currentMenu.className.replace(new RegExp("(^|\\s+)tab-currentMenu"),""); } if(!new RegExp("(^|\\s+)tab-currentMenu").test(this.className)){ this.className =this.className + " tab-currentMenu"; } 代码清单 5-84 定义 addClass 和 removeClass 函数 … GLOBAL.Dom.addClass = function(node,str){ if(!new RegExp("(^|\\s+)"+str).test(node.className)){ node.className = node.className + " " + str; } } GLOBAL.Dom.removeClass = function(node,str){ node.className = node.className.replace(new RegExp("(^|\\s+)"+str),""); } … if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,"tab-currentMenu"); } GLOBAL.Dom.addClass(this,"tab-currentMenu"); … 5.3.5 通过传参实现定制 代码清单 5-85 编写 setTab、setTab2 和 setTab3
  • menu1-1
  • menu1-2
  • menu1-3
  • menu2-1
  • menu2-2
  • menu3-1
  • menu3-2
  • menu3-3
  • menu3-4
  • menu3-5
代码清单 5-86 用参数写活变化的部分 function setTab(root,currentClass){ … if(currentClass){ var currentMenu = GLOBAL.Dom.getElementsByClassName(currentClass,root)[0]; if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,currentClass); } GLOBAL.Dom.addClass(this,currentClass); } … } var tabs = GLOBAL.Dom.getElementsByClassName("J_tab"); setTab(tabs[0]); setTab(tabs[1],"tab-currentMenu"); setTab(tabs[2],"tab-currentMenu2"); 代码清单 5-87 写活事件触发方式 … GLOBAL.namespace("Event"); GLOBAL.Event.on = function(node,eventType,handler){ node = typeof node == "string" ? document.getElementById(node) : node; if(document.all){ node.attachEvent("on"+eventType,handler); } else { node.addEventListener(eventType,handler,false); } } … function setTab(root,currentClass,trigger){ var tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu",root), tabContents = GLOBAL.Dom.getElementsByClassName("J_tab-content",root); //如果不传入激活类型,默认激活类型为点击 trigger = trigger || "click"; for(var i=0;i 5.3.6 控制 this 关键字的指向 代码清单 5-88 调试 bug … GLOBAL.Event.on(tabMenus[i],trigger,function(){ for(var j=0;jclick me // 弹出“undefined” click me // 弹出“true” click me 代码清单 5-90 setTimeout 和 setInterval 改变 this 指向 var name = "somebody"; var adang = { name : "adang", say : function(){ alert("I'm " + this.name); } }; adang.say(); // I’m adang setTimeout(adang.say,1000); // I’m someBody setInterval(adang.say,1000); // I’m someBody 代码清单 5-91 onxxx 改变 this 指向 var name = "somebody"; var btn = document.getElementById("btn"); var adang = { name : "adang", say : function(){ alert("I'm " + this.name); } }; btn.onclick = adang.say; // I’m BUTTON 代码清单 5-92 匿名函数调整 this 指向 var name = "somebody"; var btn = document.getElementById("btn"); var adang = { name : "adang", say : function(){ alert("I'm " + this.name); } }; adang.say(); // I’m adang setTimeout(function(){adang.say()},1000); // I’m adang setInterval(function(){adang.say()},1000); // I’m adang btn.onclick = function(){adang.say()}; // I’m adang setTimeout(function(){alert(this == window)},1000); // true btn.onclick = function(){alert(this == btn)}; // true 代码清单 5-93 call 和 apply 调整 this 指向 var name = "somebody"; var btn = document.getElementById("btn"); var adang = { name : "adang", say : function(){ alert("I'm " + this.name); } }; adang.say.call(btn); // I’m BUTTON setTimeout(function(){adang.say.call(btn)},1000); // I’m BUTTON setInterval(function(){adang.say.apply(btn)},1000); // I’m BUTTON btn.onclick = function(){adang.say.apply(btn)}; // I’m BUTTON 代码清单 5-94 将 this 指向的对象保存到变量 var name = "somebody"; var adang = { name : "adang", say : function(){ alert("I'm " + this.name); }, init : function(){ // this 指向 adang 对象 var This = this; document.getElementById("btn").onclick = function(){ // this 指向 btn 的 Dom 节点,This 指向 adang 对象 This.say(); // I’m adang this.say(); // 报错,this.say is not a function }; } }; adang.init(); 代码清单 5-95 调试 bug … GLOBAL.Event.on(tabMenus[i],trigger,function(){ for(var j=0;j 代码清单 5-97 加强 on 函数的功能 GLOBAL.Event.on = function(node,eventType,handler,scope){ node = typeof node == "string" ? document.getElementById(node) : node; scope = scope || node; if(document.all){ node.attachEvent("on"+eventType,function(){handler.apply(scope,arguments)}) ; } else { node.addEventListener(eventType,function(){handler.apply(scope,arguments)}, false); } } 5.3.7 预留回调接口 代码清单 5-98 设置回调函数 … function setTab(root,currentClass,trigger,handler){ var tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu",root), tabContents = GLOBAL.Dom.getElementsByClassName("J_tab-content",root); trigger = trigger || "click"; for(var i=0;i= tabMenus.length){ currentIndex = 0; } for(var i=0;i= tabMenus.length){ currentIndex = 0; } showItem(currentIndex); } if(autoPlay){ setInterval(autoHandler,playTime); } for(var i=0;i= tabMenus.length){ currentIndex = 0; } showItem(currentIndex); } if(autoPlay){ setInterval(autoHandler,playTime); } for(var i=0;i= this._tabMenus.length){ this.currentIndex = 0; } this.showItem(this.currentIndex); } } var tabs = GLOBAL.Dom.getElementsByClassName("J_tab"); new Tab({root:tabs[0],trigger:"mouseover"}); new Tab({root:tabs[1],currentClass:"tab-currentMenu",autoPlay:true,playTime:5000}); new Tab({root:tabs[2] , currentClass:"tab-currentMenu2" , trigger:"mouseover" , handler:function(index){alert("您激活的是第"+(index+1)+"个标签")}}); 5.5 其他问题 5.5.1 prototype 和内置类 代码清单 5-137 调用内置类 var a = new String("hello world"); // 通过 new String()实例化 string 类型对象 var b = "hello world"; // 直接通过""实例化 string 类型对象 alert(a.length); alert(b.length); var c = new Array(1,2,3); // 通过 new Array()实例化 array 类型对象 var d = [1,2,3]; // 直接通过[]实例化 array 类型对象 c.push(4); d.pop(); alert(c); alert(d); 代码清单 5-138 扩展内置类的行为 Array.prototype.each = function(fun){ for(var i = 0,n = this.length;in;i--){ if(o[i] == a){ o.splice(i,1); } } return o; } var a = [1,2,3,2,4,5]; var str = ""; a.each(function(v,k){ str += k + " : " + v + "\n"; }); alert(str); // 0 : 1 1:2 2:3 3:2 4:4 5:5 var b = a.map(function(v,k){ return v * 10; }); alert(a); // 1,2,3,2,4,5 alert(b); // 10,20,30,20,40,50 var c = b.Delete(20); alert(c); // 10,30,40,50 代码清单 5-139 重写内置类的方法 var a = [1,2,3]; alert(a); // 1,2,3 Array.prototype.toString = function(str){ return "I'm an array"; } alert(a); // I’m an array 代码清单 5-140 自定义 toString 方法 function Dog(o){ this.name = o; } var myDog = new Dog("wang cai"); alert(myDog); // [object Object] Dog.prototype.toString = function(){ return "my name is " + this.name; } alert(myDog); // my name is wang cai var me = { name : "adang", email : "cly84920@gmail.com", toString : function(){ return "I'm adang,my email is cly84920@gmail.com"; } } alert(me); // I'm adang,my email is cly84920@gmail.com 代码清单 5-141 重写属性 Array.prototype.length = 1; String.prototype.length = 1; alert([1,2,3].length); // 3 alert("abc".length); // 3 代码清单 5-142 扩展 Object 类 Object.prototype.test = function(){ alert("hello world"); } var a = [1,2,3],b = "abc",c = {},d = true,e = function(){}; a.test(); b.test(); c.test(); d.test(); e.test(); function Dog(o){ this.name = o; } Dog.prototype.toString = function(){ return "my name is " + this.name; } var f = new Dog("wangcai"); f.test(); 代码清单 5-143 使用自定义类 function myArray(o){ this.getArray = function(){ return o; }; } myArray.prototype = { each : function(fun){ var o = this.getArray(); for(var i=0,n=o.length;imy blog 代码清单 5-145 在 JavaScript 中获得 DOM 节点对象的属性 my blog 代码清单 5-148 自定义属性的获取 my blog 代码清单 5-149 自定义属性的反序列化 my blog 5.5.3 标签的内联事件和 event 对象 代码清单 5-150 简单的点击事件 代码清单 5-151 内联事件中的点击事件 代码清单 5-152 替换可能一 btn.onclick = handler; function handler(){ alert(arguments.length); } 代码清单 5-153 替换可能二 btn.onclick = function(){ handler(); } function handler(){ alert(arguments.length); } 代码清单 5-154 内联事件和参数 代码清单 5-155 event 对象的兼容处理 代码清单 5-156 在内联事件中兼容 event 对象 代码清单 5-157 内联事件的使用 //只弹出 1 //弹出 1 和 3 //弹出“string” 代码清单 5-158 在两处同时监听事件 代码清单 5-159 等同效果 代码清单 5-160 改进方案,同时监听两处事件 5.5.4 利用事件冒泡机制 代码清单 5-161 打分程序

阿当饭店

卫生:

价格:

味道:

代码清单 5-162 等同效果

代码清单 5-163 利用事件冒泡进行优化 // 定义 Rate 类 function Rate(rateRoot){ var root = typeof rateRoot == "string" ? document.getElementById(rateRoot) : rateRoot; var items = root.getElementsByTagName("img"); var imgs = ["star.gif","star2.gif"]; var rateFlag; for(var i=0,n=items.length;i

5.5.5 改变 DOM 样式的三种方式 代码清单 5-165 改变 DOM 节点样式的方法一 hello world 代码清单 5-166 等同效果 hello world 代码清单 5-167 用方法一改变多个样式 hello world 代码清单 5-168 等同效果 hello world 代码清单 5-169 改变 DOM 节点样式的方法二 hello world 代码清单 5-170 等同效果 hello world 代码清单 5-171 需设置样式的 DOM 节点 hello world aaaaaa bbbbbb cccccc 代码清单 5-172 等同效果一 hello world aaaaaa bbbbbb cccccc 代码清单 5-173 等同效果二 hello world aaaaaa bbbbbb cccccc 代码清单 5-174 改变 DOM 节点样式的方法三 hello world aaaaaa bbbbbb cccccc 代码清单 5-175 等同效果 hello world aaaaaa bbbbbb cccccc 附录 前端规范 附录 A 写在规则前面的话 附录 B 命名规则 html:
  • 1)XXXXXXXXXXXXXX
  • 2)XXXXXXXXXXXXXX
  • 3)XXXXXXXXXXXXXX
  • CSS: .textList{ } V .text_list{ } X .textList_firstItem{ } V .textListFirstItem{ } X .textList_firstItem{ } V .textList .firstItem{ } X 附录 C 分工安排 附录 D 注释规则 /** * 文件用途说明 * 作者姓名 * 联系方式 * 制作日期 **/ //================ // 代码用途 //================ //代码说明 //姓名 var name = "abc"; V var name ="abc"; //姓名 X 附录 E HTML 规范

    阿当制作

    阿当测试站点的页面管理模式

    附录 F CSS 规范 html:

    12345

    • 1)XXXXXXXXXXX
    • 2)XXXXXXXXXXX

    abcde

    • 1)XXXXXXXXXXX
    • 2)XXXXXXXXXXX
    CSS: .textList,.textList2{margin-top:10px;XXXXXXXXXXXXXX} .textList2{margin-top:20px;} X ===================================================== html:

    12345

    • 1)XXXXXXXXXXX
    • 2)XXXXXXXXXXX

    abcde

    • 1)XXXXXXXXXXX
    • 2)XXXXXXXXXXX
    CSS: .textList{XXXXXXXXXXXXXX} .marginTop10{margin-top:10px;} .marginTop20{margin-top:20px;} V

    XXXXXXXXXXXXX

    XXXXXXXXXXXX

    XXXXXXXXXXXXX

    X =====================================================

    XXXXXXXXXXXXX

    XXXXXXXXXXXXX

    XXXXXXXXXXXXX

    V .menu{margin:0;float:left;font-weight:bold;} V .menu{ margin:0; float:left; font-weight:bold; } X 附录 G JavaScript 规范
    还剩125页未读

    继续阅读

    下载pdf到电脑,查找使用更方便

    pdf的实际排版效果,会与网站的显示效果略有不同!!

    需要 8 金币 [ 分享pdf获得金币 ] 0 人已下载

    下载pdf

pdf贡献者

pgw6

贡献于2012-12-05

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!