目录

C o n t e n t s目录
推荐序
赞誉
前言
致谢
第 1 章从网站重构说起/1
1.1糟糕的页面实现,头疼的维护工作/2
1.2Web 标准—结构、样式和行为的分离/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 |
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 |
4.7.2id 和 class/89
4.7.3CSS 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 |
5.3.2getElementById、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.2JavaScript 的面向对象编程/224
5.4.3用面向对象方式重写代码/245
5.5其他问题/251
5.5.1prototype 和内置类/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
附录 EHTML 规范/278
附录 FCSS 规范/280
附录 GJavaScript 规范/282
第 1 章从网站重构说起
本章内容
糟糕的页面实现,头疼的维护工作
Web 标准——结构、样式和行为的分离
前端的现状
打造高品质的前端代码,提前代码的可维护性——精简、重用、有序
1.1 糟糕的页面实现,头疼的维护工作
代码清单 1-1 一个糟糕老网页的实现
<html> <head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <style type=text/css>
td,body {font-size: 15px; font-family:arial,sans-serif,宋体;} body{margin-top:0px;margin-left:0px;margin-right:0px;background-color: #fcfff7}
a:link{ color:#000000; text-decoration:none;padding-left:4px; } a:visited{COLOR: #000000; TEXT-DECORATION: none;padding-left:4px;}
a:active{color:green;text-decoration:none;padding-left:4px;}a:hover{color:red;textdecoration:underline;padding-left:4px;}
a.m:link{ color:#000000; text-decoration:none;padding-left:0px;} a.m:visited{COLOR: #000000; TEXT-DECORATION: none;padding-left:0px;}
a.m:active{color:green;text-decoration:none;padding-left:0px;} a.m:hover{color:red;text-decoration:underline;padding-left:0px;}
.t1{border-width:1px 1px 1px 1px;border-style:solid;font-size:12px;text-align:
center} .bgg{border-color:#8AB78A; width:779px}
.f9pt{font-size: 12px;} #sfont a,#sfont b{font-size:13px;}
</style> <base target="_blank">
<title>网址之家--动漫</title> <script src="js/usertrack.js"></script>
</head> <body>
<div align="center"><center> <table border="0" cellpadding="0" cellspacing="0" width="778" height="51">
<tr> <td width="230" height="51"><a href="http://www.xxx.com" target="_self"
class="m"><img src="logo.gif" alt="xxx.com" width="168" height="63"
border="0"></a></td> <td height="51" align="center"><table width="100%" border=0cellpadding=0
cellspacing=0> <form name=form1 action=http://www.baidu.com/s>
<input type=hidden name=tn value=abc> <tr>
<td colspan="2" id=sfont>
<b>网页</b>
</tr> <tr>
<td height="30" valign="top"> <input type=text name=wd size=40 onMouseOver=this.focus()
onFocus=this.select() style="margin-bottom:-5px;
font-size:16px;height:1.78em;font-family:arial,sans-serif,宋体;padding-top:2px;
padding-left:1px" maxlength=100> <input type=submit style="height:1.82em;width:6.4em;font-size:16px;
margin-bottom:-5px; padding-top:2px" value="百度一下"> </td>
<td width="80" valign="top" class="f9pt"> </td> </tr>
</form></table></td> </tr>
</table> </center></div>
<script language=javascript> <!--
UserTrack.init(1,"动漫")
document.form1.wd.focus()
//--> </script>
</body> </html>
1.2 Web 标准——结构、样式和行为的分离
代码清单 1-2 结构、样式和行为混杂的网页
<td width="100%" height="20"class="f9pt"align="center"> <font color="#346F0E">下载</font>
<input type=text name=wd size=40 onMouseOver=this.focus()
onFocus=this.select() style="margin-bottom:-5px;
font-size:16px;height:1.78em;font-family:arial,sans-serif,宋体;padding-top:2px;
padding-left:1px" maxlength=100> </td>
代码清单 1-3结构、样式和行为分别用单独文件分离开
test.html 文件:
<link rel=”stylesheet” type=”text/css” href=”test.css” /> <td class="f9pt myTd">
<span class=”myFont”>下载</span> <input type=”text” name=”wd” size=”40” id=”myInput” maxlength=”100” />
</td> <script type=”text/Javascript” src=”test.js”></script>
==============================================================
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,sansserif,宋体;padding-top:2px;padding-left:1px}
==============================================================
myInput.onmouseover = function(){ this.focus();
} myInput.onfocus = function(){
this.select();
}
代码清单 1-4 样式和行为在网页内分离开
<style type=”text/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} </style>
<td class="f9pt myTd"><span class=”myFont”>下载</span><input type=”text” name=”wd”
size=”40” id=”myInput” maxlength=”100” /></td> <script type=”text/Javascript”>
var myInput = document.getElementById(“myInput”);
myInput.onmouseover = function(){ this.focus();
} myInput.onfocus = function(){
this.select();
} </script>
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 简单页面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>阿当的简单示例</title> </head>
<body> <h1>h1 标签</h1>
<h2>h2 标签</h2> <h3>h3 标签</h3>
<p>p 标签</p> <div>div 标签</div>
<span>span 标签</span> <strong>strong 标签</strong>
<input type="text" value="input 标签" /> <textarea>textarea 标签</textarea>
<input type="button"value="提交" /> <ul>
<li>1</li> <li>2</li>
<li>3</li> <li>4</li>
<li>5</li> <li>6</li>
<li>7</li> <li>8</li>
</ul> </body>
</html>
代码清单 3-2 简单页面的 CSS 代码
h1{font-size:12px;font-weight:normal;} h2{font-size:16px;}
h3{font-size:20px;font-weight:normal;}
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 部分:
<div class=“h2”>标签的语义<a href=“#”>更多>></a></div> <div class=“p”>段落一的内容。。。<span class=“strong”>根据浏览器的默认样式 </span>。。。</div>
<div class=“p”>段落二的内容</div>
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 部分:
<h2>标签的语义 <a href=“#”>更多>></a> </h2> <p>段落一的内容。。。<strong>根据浏览器的默认样式 </strong>。。。</p>
<p>段落二的内容</p>
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 部分:
<h2>标签的语义</h2>
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 部分:
<div class=“title”> <h2>标签的语义</h2>
<a href=“#”>更多>></a> </div>
<p>段落一的内容。。。<strong>根据浏览器的默认样式 </strong>。。。</p> <p>段落二的内容</p>
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表单模块实现方案一
<form action="" method="" class="fieldset"> <div><span>帐号:</span> <input type="text" id="name" /></div>
<div><span>密码:</span> <input type="password" id="pw" /></div> <input type="submit" value="登陆" class="subBtn" />
</form>
代码清单 3-11表单模块实现方案一的语义
<表单 action=“” method=“” class=“fieldset”> <分隔><范围>帐号:</范围> <表单项 type="text" id="name" /></分隔>
<分隔><范围>密码:</范围> <表单项 type=“password” id=“pw” /></分隔> <表单项 type="submit" value="登陆" class="subBtn" />
</表单>
代码清单 3-12表单模块实现方案二
<form action="" method=""> <fieldset>
<legend>登录表单</legend> <p><label for="name">帐号:</label> <input type="text" id="name"
/></p> <p><label for="pw">密码:</label> <input type="password" id="pw"
/></p> <input type="submit" value="登陆" class="subBtn" />
</fieldset> </form>
<域集名>登录表单</域集名> <段落><表单项说明 for=“name”>帐号:</表单项说明> <表单项 type=“text” id=
“name” /></段落> <段落><表单项说明 for=“pw”>密码:</表单项说明 > <表单项 type=“password” id=
“pw” /></段落> <表单项 type="submit" value="登陆" class="subBtn" />
</域集> </表单>
代码清单 3-14表格模块实现方案一
<div class="caption">几种页面实现的比较</div> <table border="1">
<tr class="thead"><td class="th">实现方式</td><td class="th">代码量</td><td class="th">搜索引擎友好</td><td class="th">特殊终端兼容</td></tr>
<tr><td class="th">table 布局</td><td>多</td><td>差</td><td>一般</td></tr> <tr><td class="th">乱用标签的 CSS 布局</td><td>少</td><td>一般</td><td>差
</td></tr> <tr><td class="th">标签语义良好的 CSS 布局</td><td>少</td><td>好</td><td>好
</td></tr> </table>
代码清单 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布局</td><表格单元格>少</表格单元格><
表格单元格>好</表格单元格><表格单元格>好</表格单元格></表格行> </表格>
<分隔><范围>帐号:</范围> <表单项 type="text" id="name" /></分隔> <分隔><范围>密码:</范围> <表单项 type=“password” id=“pw” /></分隔>
<表单项 type="submit" value="登陆" class="subBtn" /> </表单>
代码清单 3-16表格模块实现方案二
<table border="1"> <caption>几种页面实现的比较</caption>
<thead> <tr><th>实现方式</th><th>代码量</th><th>搜索引擎友好</th><th>特殊终端兼容
</th></tr> </thead>
<tbody> <tr><th>table 布局</th><td>多</td><td>差</td><td>一般</td></tr>
<tr><th>乱用标签的CSS布局</th><td>少</td><td>一般</td><td>差</td></tr> <tr><th>标签语义良好的 CSS 布局</th><td>少</td><td>好</td><td>好</td></tr>
</tbody> </table>
代码清单 3-17表格模块实现方案二的语义
<表格 border="1"> <表格标题>几种页面实现的比较</表格标题>
</表格头部> <表格主体>
<表格行><表头>table 布局</表头><表格单元格>多</表格单元格><表格单元格>差</表格单元格><表格单元格>一般</表格单元格></表格行>
<表格行><表头>乱用标签的 CSS 布局</表头><表格单元格>少</表格单元格><表格单元格 >一般</表格单元格><表格单元格>差</表格单元格></表格行>
<表格行><表头>标签语义良好的 CSS 布局</表头><表格单元格>少</表格单元格><表格单元格>好</表格单元格><表格单元格>好</表格单元格></表格行>
</表格主体> </table>
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 的严格型 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
用于 HTML 4.01 的过渡型 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> 用于 XHTML 1.0 的严格型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 用于 XHTML 1.0 的过渡型
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
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}
.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}
.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.2CSS 的命名 —— 命名空间的概念
代码清单 4-4css 命名方案一
<style type=”text/CSS”> .timeList{xxxxxxx}
</style> <ul class=”timelist”>
<li>2009 年 08 月(3)</li> <li>2009 年 07 月(12)</li>
<li>2009 年 06 月(3)</li> <li>2009 年 05 月(8)</li>
<li>2009 年 04 月(2)</li> <li>2009 年 03 月(8)</li>
</ul>
代码清单 4-5css 命名方案二
<style type=”text/CSS”> .timeList{xxxxxxx}
.timeList li{border-bottom:xxxx;} .timeList .last{border-bottom:none;}
</style> <ul class=”timeList”>
<li>2009 年 08 月(3)</li> <li>2009 年 07 月(12)</li>
<li>2009 年 06 月(3)</li> <li>2009 年 05 月(8)</li>
<li>2009 年 04 月(2)</li> <li class=”last”>2009 年 03 月(8)</li>
</ul>
代码清单 4-6css 命名方案三
<style type=”text/CSS”>
</style> <ul class=”timeList”>
<li>2009 年 08 月(3)</li> <li>2009 年 07 月(12)</li>
<li>2009 年 06 月(3)</li> <li>2009 年 05 月(8)</li>
<li>2009 年 04 月(2)</li> <li class=”timeListLastItem”>2009 年 03 月(8)</li>
</ul>
代码清单 4-7css 命名冲突
<style type=”text/CSS”> /*made by 工程师 A*/
.timeList{xxxxxxx} .timeList li{border-bottom:xxxx;}
.timeList-lastItem{border-bottom:none;}
...
/*made by 工程师 B*/ .timeList{}
.timeList li{border-bottom:xxxx;}
</style> <!--made by 工程师 A-->
<ul class=”timeList”> <li>2009 年 08 月(3)</li>
<li>2009 年 07 月(12)</li> <li>2009 年 06 月(3)</li>
<li>2009 年 05 月(8)</li> <li>2009 年 04 月(2)</li>
<li class=”timeList-lastItem”>2009 年 03 月(8)</li> </ul>
...
<!--made by 工程师 B--> <ol class=”timeList”>
<li>2009-08-07</li> <li>2009-08-06 </li>
<li>2009-08-05</li> </ol>
代码清单 4-8css 命名加前辍
<style type=”text/CSS”> /*made by 工程师 A*/
.ad-timeList{xxxxxxx} .ad-timeList li{border-bottom:xxxx;}
.ad-timeList-lastItem{border-bottom:none;}
...
/*made by 工程师 B*/ .zx-timeList{}
.zx-timeList li{border-bottom:xxxx;}
</style>
<li>2009 年 07 月(12)</li> <li>2009 年 06 月(3)</li>
<li>2009 年 05 月(8)</li> <li>2009 年 04 月(2)</li>
<li class=”ad-timeList-lastItem”>2009 年 03 月(8)</li> </ul>
...
<!--made by 工程师 B--> <ol class=”zx-timeList”>
<li>2009-08-07</li> <li>2009-08-06 </li>
<li>2009-08-05</li> </ol>
代码清单 4-9不加前辍的命名方式
<div=”box”> <div class=”hd”></div>
<div class=”bd”></div> <div class=”ft”></div>
</div>
代码清单 4-10加前辍的命名方式
<div=”box”> <div class=”box-hd”></div>
<div class=”box-bd”></div> <div class=”box-ft”></div>
</div>
4.4.3挂多个 class 还是新建 class ——多用组合,少用继承
代码清单 4-11三个简单模块实现方案一
<style type=”text/CSS”> .numberList1{border:1px solid #ccc;padding:10px}
.numberList1 li{height:20px;line-height:20px;font-size:12px} .numberList2{border:1px solid #ccc;padding:10px;}
.numberList2 li{height:20px;line-height:20px;font-size:16px} .numberList3{border:1px solid #ccc;padding:10px;}
.numberList3 li{height:20px;line-height:20px;font-size:12px;color:red} </style>
<body> <ul class="numberList1">
<li>111111111111111111</li> <li>222222222222222222</li>
<li>333333333333333333</li> </ul>
<ul class="numberList2"> <li>444444444444444444</li>
<li>555555555555555555</li> <li>666666666666666666</li>
</ul> <ul class="numberList3">
<li>777777777777777777</li> <li>888888888888888888</li>
代码清单 4-12三个简单模块实现方案二
<style type=”text/CSS”> .numberList1,.numberList2,.numberList3{border:1px solid #ccc;padding:10px}
.numberList1 li,.numberList2 li,.numberList3 li{height:20px;line-height:20px;font-size:12px}
.numberList2 li{font-size:16px} .numberList3 li{color:red}
</style>
<body> <ul class="numberList1">
<li>111111111111111111</li> <li>222222222222222222</li>
<li>333333333333333333</li> </ul>
<ul class="numberList2"> <li>444444444444444444</li>
<li>555555555555555555</li> <li>666666666666666666</li>
</ul> <ul class="numberList3">
<li>777777777777777777</li> <li>888888888888888888</li>
<li>999999999999999999</li> </ul>
</body>
代码清单 4-13三个简单模块实现方案三
<style type=”text/CSS”> .f12{font-size:12px}
.f16{font-size:16px} .red{color:red}
.numberList{border:1px solid #ccc;padding:10px;} .numberList li{height:20px;line-height:20px;}
</style>
<body> <ul class="numberList f12">
<li>111111111111111111</li> <li>222222222222222222</li>
<li>333333333333333333</li> </ul>
<ul class="numberList f16"> <li>444444444444444444</li>
<li>555555555555555555</li> <li>666666666666666666</li>
</ul> <ul class="numberList f12 red">
<li>777777777777777777</li> <li>888888888888888888</li>
<li>999999999999999999</li> </ul>
</body>
代码清单 4-14方案二面对扩展
<style type=”text/CSS”>
.numberList1 li,.numberList2 li.,numberList3 li,numberList4 li {height:20px;line-height:20px;font-size:12px}
.numberList2 li,.numberList4 li{font-size:16px} .numberList3 li,.numberList4 li{color:red}
</style>
<body> <ul class="numberList1">
<li>111111111111111111</li> <li>222222222222222222</li>
<li>333333333333333333</li> </ul>
<ul class="numberList2"> <li>444444444444444444</li>
<li>555555555555555555</li> <li>666666666666666666</li>
</ul> <ul class="numberList3">
<li>777777777777777777</li> <li>888888888888888888</li>
<li>999999999999999999</li> </ul>
<ul class="numberList4"> <li>101010101010101010</li>
<li>111111111111111111</li> <li>121212121212121212</li>
</ul> </body>
代码清单 4-15方案三面对扩展
<style type=”text/CSS”> .f12{font-size:12px}
.f16{font-size:16px} .red{color:red}
.numberList{border:1px solid #ccc;padding:10px;} .numberList li{height:20px;line-height:20px;}
</style>
<body> <ul class="numberList f12">
<li>111111111111111111</li> <li>222222222222222222</li>
<li>333333333333333333</li> </ul>
<ul class="numberList f16"> <li>444444444444444444</li>
<li>555555555555555555</li> <li>666666666666666666</li>
</ul> <ul class="numberList f12 red">
<li>777777777777777777</li> <li>888888888888888888</li>
<li>999999999999999999</li> </ul>
<ul class="numberList f16 red"> <li>101010101010101010</li>
<li>111111111111111111</li>
代码清单 4-16YUI3 中的 class
<div class="yui-widget yui-overlay yui-widget-positioned yui-widget-stacked"> <!--Bounding Box-->
<div class="yui-overlay-content yui-widget-stdmod"> <!--Content Box-->
<div class="yui-widget-hd">Overlay Header Content</div><!--Header Section-->
<div class="yui-widget-bd">Overlay Body Content</div><!--Body Section-->
<div class="yui-widget-ft">Overlay Footer Content</div><!--Footer Section-->
</div>
<iframe class="yui-widget-shim"></iframe><!-- Stacking shim, if enabled-->
</div>
4.4.4如何处理上下 margin
代码清单 4-17提取标题组件
<style type=”text/CSS”> .title{border-bottom:1px dashed
#B2BCC6;color:#0066CF;font-size:16px;font-weight:bold;} </style>
<h2 class=”title”>服务理念</h2> …
<h2 class=”title”>服务宗旨</h2> …
<h2 class=”title”>Gsns 产品的优势</h2> …
代码清单 4-18包含 margin 的标题组件
<style type=”text/CSS”> .title1{border-bottom:1px dashed
#B2BCC6;color:#0066CF;font-size:16px;font-weight:bold;margin-top:20px;} .title2{border-bottom:1px dashed
#B2BCC6;color:#0066CF;font-size:16px;font-weight:bold;margin-top:60px;} </style>
<h2 class=”title1”>服务理念</h2> …
<h2 class=”title1”>服务宗旨</h2> …
<h2 class=”title2”>Gsns 产品的优势</h2> …
代码清单 4-19应用类的组合
<style type=”text/CSS”> .mt20{margin-top:20px;}
.mt60{margin-top:60px;}
</style>
<h2 class=”title mt20”>服务理念</h2> …
<h2 class=”title mt20”>服务宗旨</h2> …
<h2 class=”title mt60”>Gsns 产品的优势</h2> …
4.5低权重原则 —— 避免滥用子选择器
代码清单 4-20css 的层叠
<style type=”text/CSS”> span{font-size:40px}
.test{color:red} </style>
<span class=”test”>1234567890</span>
代码清单 4-21css 层叠有冲突的情况
<style type=”text/CSS”> span{font-size:40px;color:green}
.test{color:red} </style>
<span class=”test”>1234567890</span>
代码清单 4-22选择符权重相同的情况
<style type=”text/CSS”> span{font-size:40px}
.test{color:red} .test2{color:green}
</style>
<span class=”test test2”>1234567890</span>
代码清单 4-23调换样式的位置
<style type=”text/CSS”> span{font-size:40px}
.test2{color:green} .test{color:red}
</style>
<span class=”test test2”>1234567890</span>
代码清单 4-24需标红的代码
<style type=”text/CSS”> #test{font-size:14px;}
</style> <p id=”test”>CSS 选择符权重很重要</p>
代码清单 4-25用子选择器
<style type=”text/CSS”> #test{font-size:14px;}
代码清单 4-26新建 class
<style type=”text/CSS”> #test{font-size:14px;}
.font{color:red;} </style>
<p id=”test”>CSS 选择符权重<span class=”font”>很重要</span></p>
代码清单 4-27添加新的文本
<style type=”text/CSS”> #test{font-size:14px;}
#test span{color:red;} </style>
<p id=”test”>CSS 选择符权重<span>很重要</span>,我们要小心处理</p>
代码清单 4-28需标绿的代码
<style type=”text/CSS”> #test{font-size:14px;}
#test span{color:red;} .font{color:green;}
</style> <p id=”test”>CSS 选择符权重<span>很重要</span>,我们要<span class=”font”>小心处理
</span></p>
代码清单 4-29被迫加重权重的选择器
<style type=”text/CSS”> #test{font-size:14px;}
#test span{color:red;}/*选择符权重为 100+1=101*/ #test .font{color:green;}/*选择符权重为 100+10=110*/
</style> <p id=”test”>CSS 选择符权重<span>很重要</span>,我们要<span class=”font”>小心处理
</span></p>
代码清单 4-30新增 class 作为标绿容器的选择符
<style type=”text/CSS”> #test{font-size:14px;}
.font{color:red;} .font2{color:green;}
</style> <p id=”test”>CSS 选择符权重<span class=”font”>很重要</span>,我们要<span class=”font2”>
小心处理</span></p>
4.6 CSS sprite
代码清单 4-31用两张图实现高亮
<style type=”text/CSS”> .nav li{float:left; display:inline; margin-right:10px; font-family:黑体;}
.nav a{float:left; width:139px; height:31px; line-height:31px; font-size:24px;
color:#fff; text-decoration:none; text-align:center; background:url(img1.gif);} .nav a:hover{background:url(img2.gif);}
</style> <ulclass="nav">
<li><a href="#">联系我们</a></li> <li><a href="#">产品答疑</a></li>
代码清单 4-32利用一张大图的背景移动实现高亮
<style type=”text/CSS”> .nav li{float:left; display:inline; margin-right:10px; font-family:黑体;}
.nav a{float:left; width:139px; height:31px; line-height:31px; font-size:24px;
color:#fff; text-decoration:none; text-align:center; background:url(img3.gif);} .nav a:hover{background-position:0 -31px;}
</style> <ulclass="nav">
<li><a href="#">联系我们</a></li> <li><a href="#">产品答疑</a></li>
<li><a href="#">广告服务</a></li> </ul>
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.2id 和 class
4.7.3CSS hack
代码清单 4-35只在 IE 下生效
<!--[if IE]> <link type="text/CSS" href="test.css" rel="stylesheet" />
<![endif]-->
代码清单 4-36只在 IE6 下生效
<!--[if IE 6]> <link type="text/CSS" href="test.css" rel="stylesheet" />
<![endif]-->
代码清单 4-37只在 IE6 以上版本生效
<!--[if gt IE 6]> <link type="text/CSS" href="test.css" rel="stylesheet" />
<![endif]-->
代码清单 4-38只在 IE7 上不生效
<!--[if ! IE 7]>
代码清单 4-39条件注释和 style 标签
<!--[if IE 6]> <style type=”text/CSS”>
.test{} </style>
<![endif]-->
代码清单 4-40条件注释和 script 标签
<!--[if IE 6]> <script type=”text/JavaScript”>
alert(“我是 IE 6”);
</script> <![endif]-->
代码清单 4-41ie6.css、ie7.css 和 ie8.css
- ie6.css
.test{width:60px;}
- ie7.css
.test{width:70px;}
- IE 8.css
.test{width:80px;}
代码清单 4-42针对不同 IE 版本分别导入样式
<!--[if IE 6]> <link type="text/CSS" href="ie6.css" rel="stylesheet" />
<![endif]--> <!--[if gt IE 7]>
<link type="text/CSS" href="ie7.css" rel="stylesheet" /> <![endif]-->
<!--[if gt IE 8]> <link type="text/CSS" href="IE 8.css" rel="stylesheet" />
<![endif]-->
代码清单 4-43选择符前辍 hack 法
<style type=”text/CSS”>
| .test{width:80px;} | /*IE 6,IE 7,IE 8*/ |
|---|---|
| *html .test{width:60px;} | /*only for IE 6*/ |
| *+html .test{width:70px;} | /*only for IE 7*/ |
</style>
代码清单 4-44样式属性前辍 hack 法
<style type=”text/CSS”> .test{width:80px;*width:70px;_width:60px;}
</style>
4.7.4 超链接访问过后 hover 样式就不出现的问题
代码清单 4-45不正确的伪类顺序
<style type="text/CSS"> a:hover{color:yellow;}
a:visited{color:green;} </style>
<a href=”#”>hello world</a>
代码清单 4-46正确的伪类顺序
</style> <a href=”#”>hello world</a>
4.7.5hasLayout
4.7.6 块级元素和行内元素的区别
代码清单 4-47块级元素和行内元素
<style type="text/CSS"> p{background:red}
div{background:yellow} span{background:blue}
strong{background:green} </style>
<p>块级元素 p</p><div>块级元素 div</div><span>行内元素 span</span><strong>行内元素 strong</strong>
代码清单 4-48对块级元素和行内元素设置长宽
<style type="text/CSS"> p{background:red;width:200px;height:200px;}
div{background:yellow;width:400px;height:100px;} span{background:blue;width:200px;height:200px;}
strong{background:green;width:400px;height:100px;} </style>
<p>块级元素 p</p><div>块级元素 div</div><span>行内元素 span</span><strong>行内元素 strong</strong>
代码清单 4-49块级元素、行内元素的 margin 和 padding
<style type="text/CSS"> p{background:red;padding:20px;margin:20px;}
div{background:yellow;padding:20px;} span{background:blue;padding:20px;margin:20px;}
strong{background:green;padding:20px;margin:20px;} </style>
<p>块级元素 p</p><div>块级元素 div</div><span>行内元素 span</span><strong>行内元素 strong</strong>
代码清单 4-50改变块级元素和行内元素的显示
<style type="text/CSS"> p{background:red;display:inline;}
div{background:yellow;display:inline;} span{background:blue;display:block;}
strong{background:green;display:block;} </style>
<p>块级元素 p</p><div>块级元素 div</div><span>行内元素 span</span><strong>行内元素 strong</strong>
4.7.7display:inline-block 和 hasLayout
代码清单 4-51设置 display:inline-block
<style type="text/CSS"> p{color:red;width:100px;background:#ccc;height:30px;display:inline-block;}
</style> <body>
abcdefg <p>12345</p>
<style type="text/CSS"> span{color:red;width:100px;background:#ccc;height:30px;display:inline-block;}
</style> <body>
abcdefg <span>12345</span> </body>
代码清单 4-53调整竖直排列的位置
<style type="text/CSS"> span{color:red;width:100px;background:#ccc;height:30px;display:inline-block;*
vertical-align:-10px;} </style>
<body> abcdefg <span>12345</span>
</body>
4.7.8relative、absolute 和 float
4.7.9居中
代码清单 4-54行内元素的水平居中
<style type="text/CSS"> .wrap{background:#000; width:500px; height:100px; margin-bottom:10px; color:#fff;
text-align:center} </style>
<div class=”wrap”>hello world</div> <div class=”wrap”><img src=”test.gif” /></div>
代码清单 4-55确定宽度的块级元素的水平居中
<style type="text/CSS"> .wrap{background:#000; width:500px; height:100px}
.test{background:red; width:200px; height:50px; margin-left:auto;
margin-right:auto} </style>
<div class=”wrap”><div class=”test”></div></div>
代码清单 4-56 不确定宽度的块级元素的水平居中方法一
<style type="text/CSS"> ul{list-style:none; margin:0; padding:0}
table{margin-left:auto; margin-right:auto;} .test li{float:left; display:inline; margin-right:5px;}
.test a{float:left; width:20px; height:20px; text-align:center; line-height:20px;
background:#316AC5; color:#fff; border:1px solid #316AC5; text-decoration:none;} .test a:hover{background:#fff; color:#316AC5}
</style>
<div class=”wrap”> <table><tbody><tr><td>
<ul class="test"> <li><a href="#">1</a></li>
</ul> </td></tr></tbody></table>
<table><tbody><tr><td> <ul class="test">
</ul> </td></tr></tbody></table>
<table><tbody><tr><td> <ul class="test">
<li><a href="#">1</a></li> <li><a href="#">2</a></li>
<li><a href="#">3</a></li> <li><a href="#">4</a></li>
<li><a href="#">5</a></li> </ul>
</td></tr></tbody></table>
</div>
代码清单 4-57不确定宽度的块级元素的水平居中方法二
<style type="text/CSS"> ul{list-style:none;margin:0;padding:0}
.wrap{background:#000; width:500px; height:100px} .test{text-align:center;padding:5px;}
.test li{display:inline;} .test a{padding:2px 6px;background:#316AC5;color:#fff;border:1px solid
#316AC5;text-decoration:none;} .test a:hover{background:#fff;color:#316AC5}
</style>
<div class="wrap"> <ul class="test">
<li><a href="#">1</a></li> </ul>
<ul class="test"> <li><a href="#">1</a></li>
<li><a href="#">2</a></li> <li><a href="#">3</a></li>
</ul> <ul class="test">
<li><a href="#">1</a></li> <li><a href="#">2</a></li>
<li><a href="#">3</a></li> <li><a href="#">4</a></li>
<li><a href="#">5</a></li> </ul>
</div>
代码清单 4-58不确定宽度的块级元素的水平居中方法三
<style type="text/CSS"> ul{list-style:none; margin:0; padding:0}
.wrap{background:#000; width:500px; height:100px} .test{clear:both; padding-top:5px; float:left; position:relative; left:50%;}
.test li{float:left; display:inline; margin-right:5px; position:relative;
left:-50%;} .test a{float:left; width:20px; height:20px; text-align:center; line-height:20px;
background:#316AC5; color:#fff; border:1px solid #316AC5; text-decoration:none;} .test a:hover{background:#fff; color:#316AC5}
</style>
<div class="wrap"> <ul class="test">
<li><a href="#">1</a></li> <li><a href="#">2</a></li>
<li><a href="#">3</a></li> </ul>
<ul class="test"> <li><a href="#">1</a></li>
<li><a href="#">2</a></li> <li><a href="#">3</a></li>
<li><a href="#">4</a></li> <li><a href="#">5</a></li>
</ul> </div>
代码清单 4-59父元素高度不确定的文本、图片、块级元素的竖直居中
<style type="text/CSS"> .wrap{background:#000; width:500px; color:#fff; margin-bottom:10px;
padding-top:20px; padding-bottom:20px} .test{width:200px;height:50px;background:red;}
</style>
<div class="wrap">hello world</div> <div class="wrap"><img src="54.gif" /></div>
<div class="wrap"><div class="test"></div></div>
代码清单 4-60父元素高度确定的单行文本的竖直居中
<style type="text/CSS"> .wrap{background:#000; width:500px; color:#fff;height:100px;line-height:100px;}
</style>
<div class="wrap">hello world</div>
代码清单 4-61父元素高度确定的多行文本、图片、块级元素的竖直居中方法一
<style type="text/CSS"> .wrap{background:#000; width:500px; color:#fff;height:100px}
.test{width:200px;height:50px;background:red;} </style>
<table><tbody><tr><td class="wrap"> hello world<br />
hello world<br /> hello world
</td></tr></tbody></table>
<table><tbody><tr><td class="wrap"> <img src="54.gif" />
</td></tr></tbody></table>
<table><tbody><tr><td class="wrap"> <div class="test"></div>
</td></tr></tbody></table>
代码清单 4-62父元素高度确定的多行文本、图片、块级元素的竖直居中方法二
<style type="text/CSS"> .mb10{margin-bottom:10px}
.wrap{background:#000; width:500px;
color:#fff;margin-bottom:10px;height:100px;display:table-cell;vertical-align:middle
.vertical{*position:relative;*top:-50%} </style>
<div class="mb10"> <div class="wrap">
<div class="verticalWrap"> <div class="vertical">
hello world<br /> hello world<br />
hello world </div>
</div> </div>
</div> <div class="mb10">
<div class="wrap"> <div class="verticalWrap">
<img src="54.gif" class="vertical" /> </div>
</div> </div>
<div class="mb10"> <div class="wrap">
<div class="verticalWrap"> <div class="test vertical"></div>
</div> </div>
</div>
4.7.10 网格布局
代码清单 4-63两栏式布局方案一
<style type="text/CSS"> .header{}
.footer{clear:both} .sidebar{width:25%; float:left}
.main{width:70%; float:right} </style>
<div class=”header”></div> <div class=”content”>
<div class=”sidebar”></div> <div class=”main”></div>
</div> <div class=”footer”></div>
代码清单 4-64两栏式布局方案二
<style type="text/CSS"> .header{}
.footer{clear:both} .sidebar{width:25%; float:left}
.main{width:70%; float:right} </style>
<div class=”header”></div> <div class=”content”>
<div class=”main”></div>
代码清单 4-65调换左右两栏的位置
<style type="text/CSS"> .header{}
.footer{clear:both} .sidebar{width:25%; float:right}
.main{width:70%; float:left} </style>
<div class=”header”></div> <div class=”content”>
<div class=”main”></div> <div class=”sidebar”></div>
</div> <div class=”footer”></div>
代码清单 4-66用类的组合的方式设定浮动方向
<style type="text/CSS"> .fl{float:left}
.fr{float:right} .header{}
.footer{clear:both} .sidebar{width:25%}
.main{width:70%} </style>
<div class=”header”></div> <div class=”content”>
<div class=”main fr”></div> <div class=”sidebar fl”></div>
</div> <div class=”footer”></div>
代码清单 4-67用类的组合的方式面对简单修改
<style type="text/CSS"> .fl{float:left}
.fr{float:right} .header{}
.footer{clear:both} .sidebar{width:25%}
.main{width:70%} </style>
<div class=”header”></div> <div class=”content”>
<div class=”main fl”></div> <div class=”sidebar fr”></div>
</div> <div class=”footer”></div>
代码清单 4-68用类的组合的方式面对复杂修改
<style type="text/CSS"> .fl{float:left}
.fr{float:right} .content{clear:both}
.header{}
</style>
<div class=”header”></div> <div class=”content”>
<div class=”main fl”></div> <div class=”sidebar fr”></div>
</div> <div class=”content”>
<div class=”main fr”></div> <div class=”sidebar fl”></div>
</div> <div class=”footer”></div>
代码清单 4-69将宽度提取出来
<style type="text/CSS"> .fl{float:left}
.fr{float:right} .content{clear:both}
.header{} .footer{clear:both}
.sidebar{} .main{}
.w25{width:25%} .w70{width:70%}
.w35{width:35%} .w60{width:60%}
</style>
<div class=”header”></div> <div class=”content”>
<div class=”main fl w70”></div> <div class=”sidebar fr w25”></div>
</div> <div class=”content”>
<div class=”main fr w60”></div> <div class=”sidebar fl w35”></div>
</div> <div class=”footer”></div>
代码清单 4-70用子选择器应对复杂变化
<style type="text/CSS"> .content{clear:both}
.header{} .footer{clear:both}
.main{} .sidebar{}
.content-lr-7025 .main{float:left; width:70%} .content-lr-7025 .sidebar{float:right; width:25%}
.content-rl-7025 .main{float:right; width:70%} .content-rl-7025 .sidebar{float:left; width:25%}
.content-lr-6035 .main{float:left; width:60%} .content-lr-6035 .sidebar{float:right; width:35%}
.content-rl-6035 .main{float:right; width:60%} .content-rl-6035 .sidebar{float:left; width:35%}
</style>
<div class=”header”></div>
</div> <div class=”content content-rl-6035”>
<div class=”main”></div> <div class=”sidebar”></div>
</div> <div class=”footer”></div>
代码清单 4-71组合类的方式面对扩展
<style type="text/CSS"> .fl{float:left}
.fr{float:right} .content{clear:both}
.header{} .footer{clear:both}
.sidebar{} .main{}
.w25{width:25%} .w70{width:70%}
.w35{width:35%} .w60{width:60%}
.w80{width:80%} .w15{width:15%}
</style>
<div class=”header”></div> <div class=”content”>
<div class=”main fl w70”></div> <div class=”sidebar fr w25”></div>
</div> <div class=”content”>
<div class=”main fr w60”></div> <div class=”sidebar fl w35”></div>
</div> <div class=”content”>
<div class=”main fl w80”></div> <div class=”sidebar fr w15”></div>
</div> <div class=”footer”></div>
代码清单 4-72子选择器方式面对扩展
<style type="text/CSS"> .content{clear:both}
.header{} .footer{clear:both}
.main{} .sidebar{}
.content-lr-7025 .main{float:left; width:70%} .content-lr-7025 .sidebar{float:right; width:25%}
.content-rl-7025 .main{float:right; width:70%} .content-rl-7025 .sidebar{float:left; width:25%}
.content-lr-6035 .main{float:left; width:60%} .content-lr-6035 .sidebar{float:right; width:35%}
.content-rl-6035 .main{float:right; width:60%} .content-rl-6035 .sidebar{float:left; width:35%}
.content-lr-8015 .main{float:left; width:80%} .content-lr-8015 .sidebar{float:right; width:15%}
.content-rl-8015 .main{float:right; width:80%}
<div class=”header”></div> <div class=”content content-lr-7025”>
<div class=”main”></div> <div class=”sidebar”></div>
</div> <div class=”content content-rl-6035”>
<div class=”main”></div> <div class=”sidebar”></div>
</div> <div class=”content content-lr-8015”>
<div class=”main”></div> <div class=”sidebar”></div>
</div> <div class=”footer”></div>
代码清单 4-73子选择器布局的嵌套使用
<style type="text/CSS"> .content{clear:both}
.header{} .footer{clear:both}
.main{} .sidebar{}
.content-lr-7025 .main{float:left; width:70%} .content-lr-7025 .sidebar{float:right; width:25%}
.content-rl-7025 .main{float:right; width:70%} .content-rl-7025 .sidebar{float:left; width:25%}
</style>
<div class=”header”></div> <div class=”content content-lr-7025”>
<div class=”main content-lr-7025”> <div class=”main”></div>
<div class=”sidebar”></div> </div>
<div class=”sidebar”></div> </div>
<div class=”footer”></div>
4.7.11 z-index 和 Flash、IE 6 下的 select
代码清单 4-74z-index 设置高低
<style type="text/CSS"> #one{width:300px;height:300px; background:black}
#two{width:100px;height:100px; background:red;position:absolute; z-index:1;
left:100px; top:250px} #three{width:100px;height:100px; background:green; position:relative; z-index:2;
left:120px; top:-100px} </style>
<div id="one"></div> <div id="two"></div>
<div id="three"></div>
代码清单 4-75调整 z-index 的高低
<style type="text/CSS">
#three{width:100px; height:100px; background:green; position:relative; z-index:2;
left:120px; top:-100px} </style>
<div id="one"></div> <div id="two"></div>
<div id="three"></div>
代码清单 4-76z-index 设为负数
<style type="text/CSS"> #one{width:300px;height:300px; background:black}
#two{width:100px;height:100px; background:red;position:absolute; z-index:-1;
left:100px; top:250px} #three{width:100px;height:100px; background:green; position:relative; z-index:2;
left:120px; top:-100px} </style>
<div id="one"></div> <div id="two"></div>
<div id="three"></div>
代码清单 4-77为 one、two、three 监听 click 事件
<script type="text/JavaScript"> var one = document.getElementById("one"), two = document.getElementById("two"),
three = document.getElementById("three");
one.onclick = function(){ alert("one");
} two.onclick = function(){
alert("two");
} three.onclick = function(){
alert("three");
}
代码清单 4-78z-index 值相同
<style type="text/CSS"> #two{width:100px;height:100px; background:red;position:absolute; z-index:2;
left:100px; top:250px} #three{width:100px;height:100px; background:green; position:relative; z-index:2;
left:120px; top:-100px} </style>
<div id="two"></div> <div id="three"></div>
代码清单 4-79负边距引起的竖直重叠
<style type="text/CSS"> #one{width:300px; height:300px; background:black}
#two{width:100px; height:100px; background:red; margin-top:-50px} </style>
<div id="one"></div> <div id="two"></div>
代码清单 4-80负边距引起的水平重叠
<style type="text/CSS">
</style>
<div id="one"></div> <div id="two"></div>
代码清单 4-81设置 flash 的显示模式
<object width="640" height="90" type="application/x-shockwave-Flash"
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param value="xxxxxx.swf" name="movie"></param>
<param value="opaque" name="wmode"></param> <embed width="640" height="90" wmode="opaque"
type="application/x-shockwave-Flash"src="xxxxxx.swf.swf"></embed> </object>
代码清单 4-82select 表单元素
<style type="text/CSS"> #test{width:200px; height:200px; background:green; position:absolute; left:50px;
top:10px;} </style>
<select><option>-请选择-</option></select> <div id="test"></div>
代码清单 4-83用 iframe 解决 IE6 下 select 与浮起元素的显示 bug
<style type="text/CSS"> #test{width:200px; height:200px; background:green; position:absolute; left:50px;
top:10px; z-index:2} #testMask{width:200px; height:200px; position:absolute; left:50px; top:10px;
z-index:1;} </style>
<select><option>-请选择-</option></select> <div id="test"></div>
<iframe id="testMask" frameborder="0" scrolling="no"></iframe>
4.7.12 IE 6 和 png 图片
代码清单 4-84插入 png 图片
<img src=”test.png” />
代码清单 4-85一次性解决 png 透明度在 IE6 下显示问题的脚本
function correctPNG()
{ for(var i=0; i<document.images.length; i++)
{ var img = document.images[i]
var imgName = img.src.toUpperCase()
if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
{ var imgID = (img.id) ? "id='" + img.id + "' " : ""
var imgClass = (img.className) ? "class='" + img.className + "' " : ""
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt
- "' "
var imgStyle = "display:inline-block;" + img.style.cssText if (img.align == "left") imgStyle = "float:left;" + imgStyle
if (img.align == "right") imgStyle = "float:right;" + imgStyle if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
var strNewHTML = "<span " + imgID + imgClass + imgTitle
- "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
img.outerHTML = strNewHTML i = i-1
} }
} function alphaBackgrounds(){
var rslt = navigator.appVersion.match(/MSIE (d+.d+)/, '');
var itsAllGood = (rslt != null && Number(rslt[1]) >= 5.5);
for (i=0; i<document.all.length; i++){ var bg = document.all[i].currentStyle.backgroundImage;
if (bg){ if (bg.match(/.png/i) != null){
var mypng = bg.substring(5,bg.length-2);
document.all[i].style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+mypng+"',
sizingMethod='crop')";
document.all[i].style.backgroundImage = "url('')";
} }
} }
if (navigator.platform == "Win32" && navigator.appName == "Microsoft Internet Explorer"
&& window.attachEvent) { window.attachEvent("onload", correctPNG);
window.attachEvent("onload", alphaBackgrounds);
}
4.7.13 多版本 IE 并存方案——CSS 的调试利器 IETester
第 5 章高品质的 JavaScript
本章内容
养成良好的编程习惯
JavaScript 分层概念和 JavaScript 库
编程实用技巧
面向对象编程
其他问题
5.1养成良好的编程习惯
5.1.1团队合作——如何避免 js 冲突
代码清单 5-1工程师甲编写功能 A
<div> xxxxxxxxxxx
</div> <script type=”text/Javascript”>
var a = 123 , b = “hello world”;
… </script>
<div> xxxxxxxxxx
</div>
代码清单 5-2工程师乙添加功能 B
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var a = 123 , b = “hello world”;
… </script>
<div> xxxxxxxxxx
</div> <script type=”text/JavaScript”>
var a , c = ”abc”;
… </script>
<div> xxxxxxxxxx
</div>
代码清单 5-3使用匿名函数控制变量的作用域
<div> xxxxxxxxxxx
</div>
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
… })();
</script> <div>
xxxxxxxxxx </div>
代码清单 5-4功能 C 和功能 A 的通信
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
… var d = “adang is very handsome!”;
d = b + “, ” + d;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
… })();
</script> <div>
xxxxxxxxxx </div>
代码清单 5-5工程师丙添加功能 C
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var d = “adang is very handsome!”;
d = b + “, ” + d;
… })();
</script>
代码清单 5-6利用全局作用域的变量在各匿名函数间搭起桥梁
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var str;
</script> <script type=”text/JavaScript”>
(function(){ var a = 123 , str = b = “hello world”;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var b = str;
var d = “adang is very handsome!”;
d = b + “, ” + d;
… })();
</script>
代码清单 5-7添加新的全局变量
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var str,str2;
</script> <script type=”text/JavaScript”>
(function(){ var str2 = a = 123 , str = b = “hello world”;
…
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a = str2 , b = str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
</script>
代码清单 5-8用 hash 对象作为全局变量
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
</script> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
GLOBAL.str2 = a;
GLOBAL.str = b;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a = GLOBAL.str2 , b = GLOBAL.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
</script>
代码清单 5-9全局变量的冲突
<script type=”text/JavaScript”> var GLOBAL = {};
</script> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
GLOBAL.str2 = a;
GLOBAL.str = b;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
GLOBAL.str = c;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a = GLOBAL.str2 , b = GLOBAL.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var test = GLOBAL.str;
alert(test);
… })();
</script>
代码清单 5-10使用命名空间
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
</script> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
GLOBAL.A = {};
GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
…
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
GLOBAL.B = {};
GLOBAL.B.str = c;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a = GLOBAL.A.str2 , b = GLOBAL.A.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var test = GLOBAL.B.str;
alert(test);
… })();
</script>
代码清单 5-11使用多级命名空间
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
</script> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
GLOBAL.A = {};
GLOBAL.A.CAT = {};
GLOBAL.A.DOG = {};
GLOBAL.A.CAT.name = “mimi”;
GLOBAL.A.DOG.name = “wangcai”;
GLOBAL.A.CAT.move = function(){
} GLOBAL.A.DOG.move = function(){
} GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
… })();
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
</script> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
GLOBAL.namespace(“A.CAT”);
GLOBAL.namespace(“A.DOG”);
GLOBAL.A.CAT.name = “mimi”;
GLOBAL.A.DOG.name = “wangcai”;
GLOBAL.A.CAT.move = function(){
} GLOBAL.A.DOG.move = function(){
} GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
… })();
</script>
代码清单 5-13使用命名空间解决冲突的完整代码
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
</script> <script type=”text/JavaScript”>
(function(){ var a = 123 , b = “hello world”;
GLOBAL.namespace(“A.CAT”);
GLOBAL.namespace(“A.DOG”);
GLOBAL.A.CAT.name = “mimi”;
GLOBAL.A.DOG.name = “wangcai”;
GLOBAL.A.CAT.move = function(){
} GLOBAL.A.DOG.move = function(){
GLOBAL.A.str = b;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a , c = ”abc”;
GLOBAL.namespace(“B”);
GLOBAL.B.str = c;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var a = GLOBAL.A.str2 , b = GLOBAL.A.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> (function(){
var test = GLOBAL.B.str;
alert(test);
… })();
</script>
代码清单 5-14给代码添加注释
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
</script> <script type=”text/JavaScript”>
//==================================================== //功能 A
//工程师甲
//2009-11-04
GLOBAL.namespace(“A.CAT”);
GLOBAL.namespace(“A.DOG”);
GLOBAL.A.CAT.name = “mimi”;
GLOBAL.A.DOG.name = “wangcai”;
GLOBAL.A.CAT.move = function(){
} GLOBAL.A.DOG.move = function(){
} GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> //====================================================
//功能 B //工程师乙
//email:a@gmail.commsn:a@hotmail.com //2009-11-05
//==================================================== (function(){
var a , c = ”abc”;
GLOBAL.namespace(“B”);
GLOBAL.B.str = c;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> //====================================================
//功能 C //工程师丙
//email:b@yahoo.commsn:b@hotmail.com //2009-11-09
//==================================================== (function(){
var a = GLOBAL.A.str2 , b = GLOBAL.A.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> //====================================================
//功能 D //工程师丁
var test = GLOBAL.B.str;
alert(test);
… })();
</script>
5.1.2给程序一个统一的入口——window.onload 和 DOMReady
代码清单 5-15区分 javascript 的框架部分和应用部分
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
</script> <script type=”text/JavaScript”>
//==================================================== //功能 A
//工程师甲 //email:cly84920@gmail.com msn:cly84920@hotmail.com
//2009-11-04 //====================================================
(function(){ var a = 123 , b = “hello world”;
GLOBAL.namespace(“A.CAT”);
GLOBAL.namespace(“A.DOG”);
GLOBAL.A.CAT.name = “mimi”;
GLOBAL.A.DOG.name = “wangcai”;
GLOBAL.A.CAT.move = function(){
} GLOBAL.A.DOG.move = function(){
} GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> //====================================================
//功能 B //工程师乙
//2009-11-05 //====================================================
GLOBAL.B.str = c;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> //====================================================
//功能 C //工程师丙
//email:b@yahoo.commsn:b@hotmail.com //2009-11-09
//==================================================== (function(){
var a = GLOBAL.A.str2 , b = GLOBAL.A.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
</script> <div>
xxxxxxxxxx </div>
<script type=”text/JavaScript”> //====================================================
//功能 D //工程师丁
//email:c@126.commsn:c@hotmail.com //2009-11-20
//==================================================== (function(){
var test = GLOBAL.B.str;
alert(test);
… })();
</script>
代码清单 5-16给应用部分一个统一的“入口”
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
</script> <script type=”text/JavaScript”>
function init(){ //====================================================
//功能 A //工程师甲
(function(){ var a = 123 , b = “hello world”;
GLOBAL.namespace(“A.CAT”);
GLOBAL.namespace(“A.DOG”);
GLOBAL.A.CAT.name = “mimi”;
GLOBAL.A.DOG.name = “wangcai”;
GLOBAL.A.CAT.move = function(){
} GLOBAL.A.DOG.move = function(){
} GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
… })();
//==================================================== //功能 B
//工程师乙 //email:a@gmail.commsn:a@hotmail.com
//2009-11-05 //====================================================
(function(){ var a , c = ”abc”;
GLOBAL.namespace(“B”);
GLOBAL.B.str = c;
… })();
//==================================================== //功能 C
//工程师丙 //email:b@yahoo.commsn:b@hotmail.com
//2009-11-09 //====================================================
(function(){ var a = GLOBAL.A.str2 , b = GLOBAL.A.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
//==================================================== //功能 D
//工程师丁 //email:c@126.commsn:c@hotmail.com
//2009-11-20 //====================================================
(function(){ var test = GLOBAL.B.str;
alert(test);
… })();
} </script>
<div>
xxxxxxxxxx </div>
<div> xxxxxxxxxx
</div>
代码清单 5-17在 DOM 节点加载进来之前就调用
<script type="text/JavaScript"> alert(document.getElementById("test").innerHTML);
</script> <div id="test">hello world</div>
代码清单 5-18调整脚本的位置
<div id="test">hello world</div> <script type="text/JavaScript">
alert(document.getElementById("test").innerHTML);
</script>
代码清单 5-19监听 window.onload
<script type="text/JavaScript"> window.onload = function(){
alert(document.getElementById("test").innerHTML);
} </script>
<div id="test">hello world</div>
代码清单 5-20定义初始化方法的名称为 init
<script type="text/JavaScript"> function init(){
alert(document.getElementById("test").innerHTML);
} window.onload = init;
</script> <div id="test">hello world</div>
代码清单 5-21jQuery 中监听 DOMReady
<script type="text/JavaScript"
src="http://ajax.googleAPIs.com/ajax/libs/jquery/1.3/jquery.min.js"></script> <script type="text/JavaScript">
function init(){ alert(document.getElementById("test").innerHTML);
} $(document).ready(init);
</script> <div id="test">hello world</div>
代码清单 5-22YUI 中监听 DOMReady
<script type="text/JavaScript"
src="http://yui.yahooAPIs.com/combo?2.8.0r4/build/yahoo-dom-event/yahoo-dom-event.j s"></script>
<script type="text/JavaScript"> function init(){
alert(document.getElementById("test").innerHTML);
} YAHOO.util.Event.onDOMReady(init);
</script>
<script type="text/JavaScript"> function init(){
alert(document.getElementById("test").innerHTML);
} </script>
<div id="test">hello world</div> …
<script type="text/JavaScript"> init();
</script> </body>
代码清单 5-24调用 init 函数
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
</script> <script type=”text/JavaScript”>
function init(){ //====================================================
//功能 A //工程师甲
//email:cly84920@gmail.com msn:cly84920@hotmail.com //2009-11-04
//==================================================== (function(){
var a = 123 , b = “hello world”;
GLOBAL.namespace(“A.CAT”);
GLOBAL.namespace(“A.DOG”);
GLOBAL.A.CAT.name = “mimi”;
GLOBAL.A.DOG.name = “wangcai”;
GLOBAL.A.CAT.move = function(){
} GLOBAL.A.DOG.move = function(){
} GLOBAL.A.str2 = a;
GLOBAL.A.str = b;
… })();
//==================================================== //功能 B
//工程师乙
//2009-11-05 //====================================================
GLOBAL.B.str = c;
… })();
//==================================================== //功能 C
//工程师丙 //email:b@yahoo.commsn:b@hotmail.com
//2009-11-09 //====================================================
(function(){ var a = GLOBAL.A.str2 , b = GLOBAL.A.str;
var d = “adang is very handsome!”;
d = b + “, ” + d + a;
… })();
//==================================================== //功能 D
//工程师丁 //email:c@126.commsn:c@hotmail.com
//2009-11-20 //====================================================
(function(){ var test = GLOBAL.B.str;
alert(test);
… })();
} </script>
<div> xxxxxxxxxx
</div> <div>
xxxxxxxxxx </div>
<div> xxxxxxxxxx
</div> …
<script type="text/JavaScript"> init();
</script> </body>
代码清单 5-25框架部分的代码
<div> xxxxxxxxxxx
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
}
function init(){ //应用部分的 JavaScript
} </script>
<div> xxxxxxxxxx
</div> <div>
xxxxxxxxxx </div>
<div> xxxxxxxxxx
</div> …
<script type="text/JavaScript"> init();
</script> </body>
代码清单 5-26头部文件
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"> <html>
<head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>阿当制作</title> <link rel="stylesheet" type="text/CSS" href="xxx.css" />
</head> <body>
<div class="head"> ...
</div> <script type=”text/JavaScript”>
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
</script>
代码清单 5-27尾部文件
<div class="foot"> ...
</div> <script type=”text/JavaScript”>
init();
</script>
代码清单 5-28主体文件
<div>...</div> <script type=”text/JavaScript”>
function init(){ //应用部分的 JavaScript
}
<div class="foot"> ...
</div> <script type=”text/JavaScript”>
if(init){ init();
} </script>
5.1.3CSS 放在页头,JavaScript 放在页尾
代码清单 5-30有 JavaScript 和 CSS 的网页
<script type=”text/JavaScript”> window.onload = function(){
//非常多的 js 代码 …
} </script>
<div id=”test”>xxxxx</div> <!—非常多的代码-->
… <style type=”text/CSS”>
#test{} </style>
代码清单 5-31将 CSS 放在页头,JavaScript 放在页尾
<style type=”text/CSS”> #test{}
</style> <div id=”test”>xxxxx</div>
<!—非常多的代码--> …
<script type=”text/JavaScript”> window.onload = function(){
//非常多的 JavaScript 代码 …
} </script>
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.1JavaScript 如何分层
5.2.2base 层
代码清单 5-34简单的代码
<ul> <li id="item1"></li>
<li id="item2"></li> <li id="item3"></li>
</ul> <script type="text/JavaScript">
var item1 = document.getElementById("item1");
alert(item1.nextSibling.id);
</script>
代码清单 5-35查看 IE 和 firefox 下的区别
<ul> <li id="item1"></li>
<li id="item2"></li> <li id="item3"></li>
</ul> <script type="text/JavaScript">
var item1 = document.getElementById("item1");
alert(item1.nextSibling.nodeType);
alert(document.getElementsByTagName("ul")[0].childNodes.length);
</script>
代码清单 5-36去掉空格
<ul><li id="item1"></li><li id="item2"></li><li id="item3"></li></ul> <script type="text/JavaScript">
var item1 = document.getElementById("item1");
alert(item1.nextSibling.id);
</script>
代码清单 5-37分别对 IE 和 firefox 写程序
<ul> <li id="item1"></li>
<li id="item2"></li> <li id="item3"></li>
</ul> <script type="text/JavaScript">
var item1 = document.getElementById("item1");
var nextNode = item1.nextSibling;
//Firefox 不支持 document.all。这里用以判别浏览器类型 if(!document.all){
while(true){ if(nextNode.nodeType == 1){
break;
} else { if(nextNode.nextSibling){
nextNode = nextNode.nextSibling;
} else { break;
} }
</script>
代码清单 5-38针对 IE 和 firefox 分别写程序如何面对扩展
<ul> <li id="item1"></li>
<li id="item2"></li> <li id="item3"></li>
</ul> <script type="text/JavaScript">
var item1 = document.getElementById("item1");
var nextNode = item1.nextSibling;
if(!document.all){ while(true){
if(nextNode.nodeType == 1){ break;
} else { if(nextNode.nextSibling){
nextNode = nextNode.nextSibling;
} else { break;
} }
} }
alert(nextNode.id);
var item2 = document.getElementById("item2");
var nextNode2 = item2.nextSibling;
if(!document.all){ while(true){
if(nextNode2.nodeType == 1){ break;
} else { if(nextNode2.nextSibling){
nextNode2 = nextNode2.nextSibling;
} else { break;
} }
} }
alert(nextNode2.id);
</script>
代码清单 5-39用 getNextNode 函数封装 IE 和 firefox 的差异
<ul> <li id="item1"></li>
<li id="item2"></li> <li id="item3"></li>
</ul> <script type="text/JavaScript">
function getNextNode(node){ node = typeof node == "string" ? document.getElementById(node) : node;
var nextNode = node.nextSibling;
if(!nextNode) return null;
if(!document.all){ while(true){
if(nextNode.nextSibling){ nextNode = nextNode.nextSibling;
} else { break;
} }
} }
return nextNode;
};
var nextNode = getNextNode("item1");
alert(nextNode.id);
var nextNode2 = getNextNode("item2");
alert(nextNode2.id);
</script>
代码清单 5-40针对 IE 和 firefox 分别设置透明度
<style type="text/CSS"> #test1{background:blue;height:100px;}
#test2{background:green;height:100px;} </style>
<div id="test1"></div> <div id="test2"></div>
<script type="text/JavaScript"> var test1 = document.getElementById("test1"),test2 =
document.getElementById("test2");
if (document.all){ test1.style.filter = 'alpha(opacity=20)';
test2.style.filter = 'alpha(opacity=80)';
} else { test1.style.opacity = 0.2;
test2.style.opacity = 0.8;
} </script>
代码清单 5-41封装 setOpacity 函数
<style type="text/CSS"> #test1{background:blue;height:100px;}
#test2{background:green;height:100px;} </style>
<div id="test1"></div> <div id="test2"></div>
<script type="text/JavaScript"> function setOpacity(node, level){
node = typeof node == "string" ? document.getElementById(node) : node;
if (document.all){ node.style.filter = 'alpha(opacity=' + level + ')';
} else { node.style.opacity = level / 100;
} }
setOpacity("test1",20);
setOpacity("test2",80);
</script>
代码清单 5-42点击事件和参数
<input type="button" value="click me" id="btn" />
alert(arguments.length);
} </script>
代码清单 5-43兼容 IE 和 firefox 的 event 对象
<input type="button" value="click me" id="btn" /> <script type="text/JavaScript">
var btn = document.getElementById("btn");
btn.onclick = function(e){ e = window.event || e;
//下面可以用 e 来做点什么事,e 在 IE 和 Firefox 下都指向了 event 对象 }
</script>
代码清单 5-44兼容 srcElement 和 target
<input type="button" value="click me" id="btn" /> <span id="span">hello world</span>
<script type="text/JavaScript"> document.getElementById("btn").onclick = function(e){
e = window.event || e;
var el = e.srcElement || e.target;
alert(el.tagName);
} document.getElementById("span").onclick = function(e){
e = window.event || e;
var el = e.srcElement || e.target;
alert(el.tagName);
} </script>
代码清单 5-45封装 getEventTarget 函数
<input type="button" value="click me" /> <span id="span">hello world</span>
<script type="text/JavaScript"> function getEventTarget(e){
e = window.event || e;
return e.srcElement || e.target;
} document.getElementById("wrapper").onclick = function(e){
var node = getEventTarget(e);
alert(node.tagName);
} document.getElementById("span").onclick = function(e){
var node = getEventTarget(e);
alert(node.tagName);
} </script>
代码清单 5-46event 对象的冒泡
<style type="text/CSS"> #infoBox{padding:5px;border:2px dashed
#ccc;margin-bottom:10px;width:136px;height:20px;line-height:20px;text-align:center;
} #wrapper{padding:20px 0;background:black;width:150px;text-align:center;}
</style> <p id="infoBox"></p>
<script type="text/JavaScript"> var infoBox = document.getElementById("infoBox") , wrapper =
document.getElementById("wrapper") , btn = document.getElementById("btn");
wrapper.onclick = function(){ infoBox.innerHTML = "你点击的是:div";
} btn.onclick = function(){
infoBox.innerHTML = "你点击的是:input";
} </script>
代码清单 5-47监测冒泡的过程
<style type="text/CSS"> #infoBox{padding:5px;border:2px dashed
#ccc;margin-bottom:10px;width:136px;height:20px;line-height:20px;text-align:center;
} #wrapper{padding:20px 0;background:black;width:150px;text-align:center;}
</style> <p id="infoBox"></p>
<div id="wrapper"> <input type="button" value="click me" id="btn" />
</div> <script type="text/JavaScript">
var infoBox = document.getElementById("infoBox") , wrapper = document.getElementById("wrapper") , btn = document.getElementById("btn");
wrapper.onclick = function(){ infoBox.innerHTML = "你点击的是:div";
alert(1);
} btn.onclick = function(){
infoBox.innerHTML = "你点击的是:input";
alert(2);
} </script>
代码清单 5-48阻止事件冒泡
<style type="text/CSS"> #infoBox{padding:5px;border:2px dashed
#ccc;margin-bottom:10px;width:136px;height:20px;line-height:20px;text-align:center;
} #wrapper{padding:20px 0;background:black;width:150px;text-align:center;}
</style> <p id="infoBox"></p>
<div id="wrapper"> <input type="button" value="click me" id="btn" />
</div> <script type="text/JavaScript">
var infoBox = document.getElementById("infoBox") , wrapper = document.getElementById("wrapper") , btn = document.getElementById("btn");
wrapper.onclick = function(){ infoBox.innerHTML = "你点击的是:div";
} btn.onclick = function(e){
infoBox.innerHTML = "你点击的是:input";
e = window.event || e;
if(document.all){ e.cancelBubble=true;
} </script>
代码清单 5-49封装 stopPropagation 函数
<style type="text/CSS"> #infoBox{padding:5px;border:2px dashed
#ccc;margin-bottom:10px;width:136px;height:20px;line-height:20px;text-align:center;
} #wrapper{padding:20px 0;background:black;width:150px;text-align:center;}
</style> <p id="infoBox"></p>
<div id="wrapper"> <input type="button" value="click me" id="btn" />
</div> <script type="text/JavaScript">
function stopPropagation(e){ e = window.event || e;
if(document.all){ e.cancelBubble=true;
} else { e.stopPropagation();
} }
var infoBox = document.getElementById("infoBox") , wrapper = document.getElementById("wrapper") , btn = document.getElementById("btn");
wrapper.onclick = function(){ infoBox.innerHTML = "你点击的是:div";
} btn.onclick = function(e){
infoBox.innerHTML = "你点击的是:input";
stopPropagation(e);
} </script>
代码清单 5-50监听 click 事件
<input type="button" value="click me" id="btn" /> <script type="text/JavaScript">
var btn = document.getElementById("btn");
btn.onclick = function(){ alert(1);
} </script>
代码清单 5-51监听两个 click 事件
<input type="button" value="click me" id="btn" /> <script type="text/JavaScript">
var btn = document.getElementById("btn");
btn.onclick = function(){ alert(1);
} btn.onclick = function(){
alert(2);
} </script>
代码清单 5-52on xxx 在多人合作时的冲突问题
// 功能 A,made by 工程师甲 //===========================
(function(){ …
var btn = document.getElementById("btn");
btn.onclick = function(){ alert(1);
} …
})();
//========================== // 功能 B,made by 工程师乙
//=========================== (function(){
… var btn = document.getElementById("btn");
btn.onclick = function(){ alert(2);
} …
})();
</script>
代码清单 5-53使用 attachEvent 和 addEventListener 代替 on xxx
<input type="button" value="click me" id="btn" /> <script type="text/JavaScript">
var btn = document.getElementById("btn");
if(document.all){ btn.attachEvent("onclick",function(){
alert(1);
});
} else { btn.addEventListener("click",function(){
alert(1);
},false);
} if(document.all){
btn.attachEvent("onclick",function(){ alert(2);
});
} else { btn.addEventListener("click",function(){
alert(2);
},false);
} </script>
代码清单 5-54封装 on 函数
<input type="button" value="click me" id="btn" /> <script type="text/JavaScript">
function on(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);
}
alert(1);
});
on(btn,"click",function(){ alert(2);
})
</script>
代码清单 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 函数
<span class="a">1</span>
<strong class="b">5</strong> <div id="wrapper"><strong class="b">6</strong></div>
<script type="text/JavaScript"> function getElementsByClassName(str,root,tag){
if(root){ root = typeof root == "string" ? document.getElementById(root) : root;
} else { root = document.body;
} tag = tag || "*";
var els = root.getElementsByTagName(tag),arr = [];
for(var i=0,n=els.length;i<n;i++){ for(var j=0,k=els[i].className.split(" "),l=k.length;j<l;j++){
if(k[j] == str){ arr.push(els[i]);
break;
} }
} return arr;
} var aEls = getElementsByClassName("a") , bEls =
getElementsByClassName("b","wrapper") , bEls2 = getElementsByClassName("b",null,"strong");
| alert(aEls.length); | // 3 | (1,2,3) |
|---|---|---|
| alert(bEls.length); | // 1 | (6) |
| alert(bEls2.length); | // 2 | (5,6) |
| 代码清单5-59 定义extend函数 |
function extend(subClass,superClass){ var F = function(){};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor){ superClass.prototype.constructor = superClass;
} }
function Animal(name){ this.name = name;
this.type = "animal"
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
function Bird(name){ this.constructor.superclass.constructor.apply(this,arguments);
this.type = "bird"
} extend(Bird,Animal);
Bird.prototype.fly = function(){ alert("I'm flying");
canary.fly();// I’m flying
代码清单 5-60使用命名空间
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
//Dom 相关 GLOBAL.namespace("Dom");
GLOBAL.Dom.getNextNode = function(node){ node = typeof node == "string" ? document.getElementById(node) : node;
var nextNode = node.nextSibling;
if(!nextNode) return null;
if(!document.all){ while(true){
if(nextNode.nodeType == 1){ break;
} else { if(nextNode.nextSibling){
nextNode = nextNode.nextSibling;
} else { break;
} }
} }
return nextNode;
};
GLOBAL.Dom.setOpacity = function(node, level){ node = typeof node == "string" ? document.getElementById(node) : node;
if (document.all){ node.style.filter = 'alpha(opacity=' + level + ')';
} else { node.style.opacity = level / 100;
} }
GLOBAL.Dom.get = function(node){ node = typeof node == "string" ? document.getElementById(node) : node;
return node;
} GLOBAL.Dom.getElementsByClassName = function(str,root,tag){
if(root){ root = typeof root == "string" ? document.getElementById(root) : root;
} else { root = document.body;
} tag = tag || "*";
var els = root.getElementsByTagName(tag),arr = [];
for(var i=0,n=els.length;i<n;i++){ for(var j=0,k=els[i].className.split(" "),l=k.length;j<l;j++){
if(k[j] == str){ arr.push(els[i]);
} return arr;
}
//Event 相关 GLOBAL.namespace("Event");
GLOBAL.Eevent.getEventTarget = function(e){ e = window.event || e;
return e.srcElement || e.target;
} GLOBAL.Event.stopPropagation = function(e){
e = window.event || e;
if(document.all){ e.cancelBubble=true;
} else { e.stopPropagation();
} }
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);
} }
//Lang 相关 GLOBAL.namespace("Lang");
GLOBAL.Lang.trim = function(ostr){ return ostr.replace(/^\s+|\s+$/g,"");
} GLOBAL.Lang.isNumber = function(s){
return !isNaN(s);
} GLOBAL.Lang.extend = function(subClass,superClass){
var F = function(){};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor){ superClass.prototype.constructor = superClass;
} }
代码清单 5-61引入 common.js
<script type="text/JavaScript" src="base.js"></script> <script type="text/JavaScript" src="common.js"></script>
代码清单 5-62设置 cookie
document.cookie = "cookieName = cookieValue; expirationdate = timeValue; path = pathValue";
代码清单 5-63读写 cookie
// 设置 cookie
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 组件
<script type="text/JavaScript" src="base.js"></script> <script type="text/JavaScript" src="common_drag.js"></script>
<script type="text/JavaScript" src="common_msg.js"></script>
5.2.4page 层
5.2.5JavaScript 库
5.3编程实用技巧
5.3.1弹性
代码清单 5-66开始编写 Tab 组件
.tab-menuWrapper li{float:left;display:inline;padding:5px;border:1px solid #333;border-bottom:none;margin-right:5px;}
.tab-contentWrapper{border:1px solid #333;clear:left;padding:5px;} </style>
<div class="tab"> <ul class="tab-menuWrapper">
<li>menu1</li> <li>menu2</li>
<li>menu3</li> </ul>
<div class="tab-contentWrapper"> <div>content1</div>
<div style="display:none">content2</div> <div style="display:none">content3</div>
</div> </div>
代码清单 5-67给 html 标签挂上 id
… <div class="tab">
<ul class="tab-menuWrapper"> <li id="tab-menu1">menu1</li>
<li id="tab-menu2">menu2</li> <li id="tab-menu3">menu3</li>
</ul> <div class="tab-contentWrapper">
<div id="tab-content1">content1</div> <div id="tab-content2" style="display:none">content2</div>
<div id="tab-content3" style="display:none">content3</div> </div>
</div> <script type="text/JavaScript">
//获得 tabMenu 和 tabContent 的 DOM 节点,并保存在变量中 var tabMenu1 = document.getElementById("tab-menu1") ,
tabMenu2 = document.getElementById("tab-menu2") , tabMenu3 = document.getElementById("tab-menu3") ,
tabContent1 = document.getElementById("tab-content1") , tabContent2 = document.getElementById("tab-content2") ,
tabContent3 = document.getElementById("tab-content3");
//让 tabMenu 监听点击 click 事件 tabMenu1.onclick = function(){
//显示 tabContent1,隐藏 tabContent2 和 tabContent3 tabContent1.style.display = "block";
tabContent2.style.display = "none";
tabContent3.style.display = "none";
} tabMenu2.onclick = function(){
//显示 tabContent2,隐藏 tabContent1 和 tabContent3 tabContent1.style.display = "none";
tabContent2.style.display = "block";
tabContent3.style.display = "none";
} tabMenu3.onclick = function(){
//显示 tabContent3,隐藏 tabContent1 和 tabContent2 tabContent1.style.display = "none";
tabContent2.style.display = "none";
代码清单 5-68提高 Tab 的扩展性
… <div class="tab">
<ul class="tab-menuWrapper" id="tab-menuWrapper"> <li>menu1</li>
<li>menu2</li> <li>menu3</li>
<li>menu4</li> </ul>
<div class="tab-contentWrapper" id="tab-contentWrapper"> <div>content1</div>
<div style="display:none">content2</div> <div style="display:none">content3</div>
<div style="display:none">content4</div> </div>
</div> <script type="text/JavaScript">
//获得 tabMenu 和 tabContent 的节点,并以数组的形式保存在变量中 var tabMenus =
document.getElementById("tab-menuWrapper").getElementsByTagName("li") , tabContents =
document.getElementById("tab-contentWrapper").getElementsByTagName("div");
//遍历数组,让 tabMenu 监听 click 事件 for(var i=0;i<tabMenus.length;i++){
tabMenus[i].onclick = function(){ //遍历数组,隐藏所有 tabContent
for(var j=0;j<tabContents.length;j++){ tabContents[j].style.display = "none";
} //显示被点击的 tabMenu 对应的 tabContent
tabContents[i].style.display = "block";
} }
</script>
代码清单 5-69循环中的 i
for(var i=0;i<tabMenus.length;i++){ tabMenus[i].onclick = function(){
//弹出当前索引 alert(i);
//遍历数组,隐藏所有 tabContent for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
} //显示被点击的 tabMenu 对应的 tabContent
tabContents[i].style.display = "block";
} }
代码清单 5-70解决循环 bug 方法一
for(var i=0;i<tabMenus.length;i++){ (function(_i){
tabMenus[_i].onclick = function(){ for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
})(i);
}
代码清单 5-71解决循环 bug 方法二
for(var i=0;i<tabMenus.length;i++){ tabMenus[i]._index = i;
tabMenus[i].onclick = function(){ for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
} tabContents[this._index].style.display = "block";
} }
代码清单 5-72两个标签的 Tab
<!—- 两个标签 --> <div class="tab">
<ul class="tab-menuWrapper" id="tab-menuWrapper"> <li>menu1</li>
<li>menu2</li> </ul>
<div class="tab-contentWrapper" id="tab-contentWrapper"> <div>content1</div>
<div style="display:none">content2</div> </div>
</div>
代码清单 5-73五个标签的 Tab
<!—- 五个标签 --> <div class="tab">
<ul class="tab-menuWrapper" id="tab-menuWrapper"> <li>menu1</li>
<li>menu2</li> <li>menu3</li>
<li>menu4</li> <li>menu5</li>
</ul> <div class="tab-contentWrapper" id="tab-contentWrapper">
<div>content1</div> <div style="display:none">content2</div>
<div style="display:none">content3</div> <div style="display:none">content4</div>
<div style="display:none">content5</div> </div>
</div>
代码清单 5-74结构稍复杂的 Tab
<div class="tab"> <ul class="tab-menuWrapper" id="tab-menuWrapper">
<li>menu1</li> <li>menu2</li>
<li>menu3</li> </ul>
<div class="tab-contentWrapper" id="tab-contentWrapper"> <div><div>content1</div><ul><li>abc</li></ul></div>
<div style="display:none"><p>content2</p><div>abc</div></div>
代码清单 5-75复杂 Tab 结构带来的问题
<div class="tab"> <ul class="tab-menuWrapper" id="tab-menuWrapper">
<li>menu1</li> <li>menu2</li>
<li>menu3</li> </ul>
<div class="tab-contentWrapper" id="tab-contentWrapper"> <div><div>content1</div><ul><li>abc</li></ul></div>
<div style="display:none"><p>content2</p><div>abc</div></div> <div style="display:none">content3</div>
</div> </div>
<script type="text/JavaScript"> var tabMenus =
document.getElementById("tab-menuWrapper").getElementsByTagName("li") , tabContents =
document.getElementById("tab-contentWrapper").getElementsByTagName("div");
alert(tabContents.length);
//弹出 5,不是 3 …
5.3.2getElementById、getElementsByTagName和
getElementsByClassName
代码清单 5-76使用 getElementsByClassName
… <div class="tab">
<ul class="tab-menuWrapper" id="tab-menuWrapper"> <li>menu1</li>
<li>menu2</li> <li>menu3</li>
</ul> <div class="tab-contentWrapper">
<div class="J_tab-content"><div>content1</div><ul>abc</ul></div> <div class="J_tab-content"
style="display:none"><p>content2</p><div>abc</div></div> <div class="J_tab-content" style="display:none">content3</div>
</div> </div>
<script type="text/JavaScript"> var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
GLOBAL.namespace("Dom");
GLOBAL.Dom.getElementsByClassName = function(str,root,tag){ if(root){
root = typeof root == "string" ?
document.getElementById(root) : root;
} else {
var els = root.getElementsByTagName(tag),arr = [];
for(var i=0,n=els.length;i<n;i++){ for(var j=0,k=els[i].className.split("
"),l=k.length;j<l;j++){ if(k[j] == str){
arr.push(els[i]);
break;
} }
} return arr;
}
var tabMenus = document.getElementById("tab-menuWrapper").getElementsByTagName("li"),
tabContents = GLOBAL.Dom.getElementsByClassName("J_tab-content");
for(var i=0;i<tabMenus.length;i++){ tabMenus[i]._index = i;
tabMenus[i].onclick = function(){ for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
} tabContents[this._index].style.display = "block";
} }
</script>
5.3.3可复用性
代码清单 5-77将 id 换为 class
… <div class="tab">
<ul class="tab-menuWrapper"> <li class="J_tab-menu">menu1</li>
<li class="J_tab-menu">menu2</li> <li class="J_tab-menu">menu3</li>
</ul> …
var tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu");
…
代码清单 5-78三个 Tab
<div class="tab"> <ul class="tab-menuWrapper">
<li class="J_tab-menu">menu1-1</li> <li class="J_tab-menu">menu1-2</li>
<li class="J_tab-menu">menu1-3</li> </ul>
<div class="tab-contentWrapper"> <div class="J_tab-content"><div>content1-1</div><ul>abc</ul></div>
<div class="J_tab-content"
style="display:none"><p>content1-2</p><div>abc</div></div> <div class="J_tab-content" style="display:none">content1-3</div>
</div> </div>
<li class="J_tab-menu">menu2-2</li> </ul>
<div class="tab-contentWrapper"> <div class="J_tab-content"><div>content2-1</div><ul>abc</ul></div>
<div class="J_tab-content"
style="display:none"><p>content2-2</p><div>abc</div></div> </div>
</div> <div class="tab">
<ul class="tab-menuWrapper"> <li class="J_tab-menu">menu3-1</li>
<li class="J_tab-menu">menu3-2</li> <li class="J_tab-menu">menu3-3</li>
<li class="J_tab-menu">menu3-4</li> <li class="J_tab-menu">menu3-5</li>
</ul> <div class="tab-contentWrapper">
<div class="J_tab-content"><div>content3-1</div><ul>abc</ul></div> <div class="J_tab-content"
style="display:none"><p>content3-2</p><div>abc</div></div> <div class="J_tab-content" style="display:none">content3-3</div>
<div class="J_tab-content"
style="display:none"><p>content3-4</p><div>abc</div></div> <div class="J_tab-content" style="display:none">content3-5</div>
</div> </div>
代码清单 5-79给 Tab 添加根结点挂钩
… <div class="tab J_tab">
<ul class="tab-menuWrapper"> …
</ul> <div class="tab-contentWrapper">
… </div>
</div> <div class="tab J_tab">
<ul class="tab-menuWrapper"> …
</ul> <div class="tab-contentWrapper">
… </div>
</div> <div class="tab J_tab">
<ul class="tab-menuWrapper"> …
</ul> <div class="tab-contentWrapper">
… </div>
</div> <script type="text/JavaScript">
…
function setTab(root){
tabMenus[i]._index = i;
tabMenus[i].onclick = function(){ for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
} tabContents[this._index].style.display = "block";
} }
}
var tabs = GLOBAL.Dom.getElementsByClassName("J_tab");
for(var i=0;i<tabs.length;i++){ setTab(tabs[i]);
} </script>
5.3.4避免产生副作用
代码清单 5-80高亮当前 Tab
<style type="text/CSS"> …
.tab .tab-currentMenu{background-color:#333;color:#fff;} </style>
<div class="tab J_tab"> <ul class="tab-menuWrapper">
<li class="J_tab-menu .tab-currentMenu">menu1-1</li> <li class="J_tab-menu">menu1-2</li>
<li class="J_tab-menu">menu1-3</li> </ul>
<div class="tab-contentWrapper"> …
</div> </div>
<div class="tab J_tab"> <ul class="tab-menuWrapper">
<li class="J_tab-menu .tab-currentMenu">menu2-1</li> <li class="J_tab-menu">menu2-2</li>
</ul> <div class="tab-contentWrapper">
… </div>
</div> <div class="tab J_tab">
<ul class="tab-menuWrapper"> <li class="J_tab-menu .tab-currentMenu">menu3-1</li>
<li class="J_tab-menu">menu3-2</li> <li class="J_tab-menu">menu3-3</li>
<li class="J_tab-menu">menu3-4</li> <li class="J_tab-menu">menu3-5</li>
</ul> <div class="tab-contentWrapper">
… </div>
</div> <script type="text/JavaScript">
…
for(var i=0;i<tabMenus.length;i++){ tabMenus[i]._index = i;
tabMenus[i].onclick = function(){ for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
} tabContents[this._index].style.display = "block";
//如果有当前选中标签,则去掉“tab-currentMenu”
var currentMenu = GLOBAL.Dom.getElementsByClassName("tab-currentMenu",root)[0];
if(currentMenu){ currentMenu.className = "";
} //给当前被点击的按钮挂上当前选中的 class
this.className = "tab-currentMenu";
} }
} …
</script>
代码清单 5-81修改 className
if(currentMenu){ currentMenu.className = "";
} this.className = "tab-currentMenu";
代码清单 5-82修改 className 引起的冲突
<style type="text/CSS"> …
.tab .tab-currentMenu{background-color:#333;color:#fff;} .underLine{text-decoration:underline;}
</style> …
<div class="tab"> <ul class="tab-menuWrapper">
<li class="J_tab-menu">menu1-1</li> <li class="J_tab-menu">menu1-2</li>
<li class="J_tab-menu underLine">menu1-3</li> </ul>
…
代码清单 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;
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
<style type="text/CSS"> …
.tab .tab-currentMenu{background-color:#333;color:#fff;} .tab .tab-currentMenu2{background-color:blue;color:#fff;}
.underLine{text-decoration:underline;} </style>
<div class="tab J_tab"> <ul class="tab-menuWrapper">
<li class="J_tab-menu">menu1-1</li> <li class="J_tab-menu">menu1-2</li>
<li class="J_tab-menu">menu1-3</li> </ul>
<div class="tab-contentWrapper"> …
</div> </div>
<div class="tab J_tab"> <ul class="tab-menuWrapper">
<li class="J_tab-menu .tab-currentMenu">menu2-1</li> <li class="J_tab-menu">menu2-2</li>
</ul> <div class="tab-contentWrapper">
… </div>
</div> <div class="tab J_tab">
<ul class="tab-menuWrapper"> <li class="J_tab-menu .tab-currentMenu2">menu3-1</li>
<li class="J_tab-menu">menu3-2</li> <li class="J_tab-menu">menu3-3</li>
<li class="J_tab-menu">menu3-4</li> <li class="J_tab-menu">menu3-5</li>
</ul> <div class="tab-contentWrapper">
… </div>
</div> <script type="text/JavaScript">
… function setTab(root){
… //去掉高亮当前标签的功能
/* var currentMenu =
} GLOBAL.Dom.addClass(this,"tab-currentMenu");
*/ …
} function setTab2(root){
… //当前标签挂上高亮样式 1
var currentMenu = GLOBAL.Dom.getElementsByClassName("tab-currentMenu",root)[0];
if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,"tab-currentMenu");
} GLOBAL.Dom.addClass(this,"tab-currentMenu");
… }
function setTab3(root){ …
//当前标签挂上高亮样式 2 var currentMenu =
GLOBAL.Dom.getElementsByClassName("tab-currentMenu2",root)[0];
if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,"tab-currentMenu2");
} GLOBAL.Dom.addClass(this,"tab-currentMenu2");
… }
var tabs = GLOBAL.Dom.getElementsByClassName("J_tab");
setTab(tabs[0]);
setTab2(tabs[1]);
setTab3(tabs[2]);
</script>
代码清单 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");
</script>
代码清单 5-87写活事件触发方式
… GLOBAL.namespace("Event");
GLOBAL.Event.on = function(node,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<tabMenus.length;i++){ tabMenus[i]._index = i;
//调用 base 层提供的 on 方法 GLOBAL.Event.on(tabMenus[i],trigger,function(){
for(var j=0;j<tabContents.length;j++){ tabContents[j].style.display = "none";
} tabContents[this._index].style.display = "block";
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");
//将 Tab1 和 Tab3 的标签激活方式改为 mouseover setTab(tabs[0],null,"mouseover");
setTab(tabs[1],"tab-currentMenu");
setTab(tabs[2],"tab-currentMenu2","mouseover");
</script>
5.3.6控制 this 关键字的指向
代码清单 5-88调试 bug
… GLOBAL.Event.on(tabMenus[i],trigger,function(){
for(var j=0;j<tabContents.length;j++){ tabContents[j].style.display = "none";
} alert(this._index);
tabContents[this._index].style.display = "block";
代码清单 5-89javascript 伪协议和内联事件
// 弹出“A”
<a href="#" onclick="alert(this.tagName)">click me</a> // 弹出“undefined”
<a href="JavaScript:alert(this.tagName)">click me</a> // 弹出“true”
<a href="JavaScript:alert(this == window)">click me</a>
代码清单 5-90setTimeout 和 setInterval 改变 this 指向
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指向 |
<input type="button" value="click me" id="btn" name="BUTTON" />
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 指向
<input type="button" value="click me" id="btn" name="BUTTON" />
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指向 |
<input type="button" value="click me" id="btn" name="BUTTON" />
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 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<tabContents.length;j++){ tabContents[j].style.display = "none";
} alert(this == window);
tabContents[this._index].style.display = "block";
代码清单 5-96attachEvent、addEventListener 和 this 指针
<input type="button" value="click me" id="btn" /> <script type="text/JavaScript">
var btn = document.getElementById("btn");
if(document.all){ // ie
btn.attachEvent("onclick",function(){ alert(this.tagName);//undefined
alert(this == window);//true });
} else { // Firefox
btn.addEventListener("click",function(){ alert(this.tagName);//INPUT
alert(this == window);//false },false);
} </script>
代码清单 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;i++){ tabMenus[i]._index = i;
GLOBAL.Event.on(tabMenus[i],trigger,function(){ for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
} tabContents[this._index].style.display = "block";
if(currentClass){ var currentMenu =
GLOBAL.Dom.getElementsByClassName(currentClass,root)[0];
if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,currentClass);
} GLOBAL.Dom.addClass(this,currentClass);
} if(handler){
handler(this._index);
} });
} }
var tabs = GLOBAL.Dom.getElementsByClassName("J_tab");
setTab(tabs[0],null,"mouseover");
setTab(tabs[1],"tab-currentMenu");
setTab(tabs[2],"tab-currentMenu2","mouseover",function(index){alert("您激活的是第 "+(index+1)+"个标签")});
5.3.8don’t repeat yourself
代码清单 5-99添加自动切换功能
… function setTab(root,currentClass,trigger,handler,autoPlay,playTime){
var tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu",root), tabContents = GLOBAL.Dom.getElementsByClassName("J_tab-content",root);
trigger = trigger || "click";
playTime = playTime || 3000;
var currentIndex = 0;
function autoHandler(){ currentIndex++;
if(currentIndex >= tabMenus.length){ currentIndex = 0;
} for(var i=0;i<tabContents.length;i++){
tabContents[i].style.display = "none";
} tabContents[currentIndex].style.display = "block";
if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,currentClass);
} GLOBAL.Dom.addClass(tabMenus[currentIndex],currentClass);
} if(handler){
handler(currentIndex);
} }
if(autoPlay){ setInterval(autoHandler,playTime);
} for(var i=0;i<tabMenus.length;i++){
tabMenus[i]._index = i;
GLOBAL.Event.on(tabMenus[i],trigger,function(){ for(var j=0;j<tabContents.length;j++){
tabContents[j].style.display = "none";
} tabContents[this._index].style.display = "block";
if(currentClass){ var currentMenu =
GLOBAL.Dom.getElementsByClassName(currentClass,root)[0];
if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,currentClass);
} GLOBAL.Dom.addClass(this,currentClass);
} if(handler){
handler(this._index);
} currentIndex = this._index;
});
} }
var tabs = GLOBAL.Dom.getElementsByClassName("J_tab");
setTab(tabs[0],null,"mouseover");
setTab(tabs[1],"tab-currentMenu",null,null,true,5000);
setTab(tabs[2],"tab-currentMenu2","mouseover",function(index){alert("您激活的是第 "+(index+1)+"个标签")});
代码清单 5-100重构代码,将相同代码提取出来
… function setTab(root,currentClass,trigger,handler,autoPlay,playTime){
var tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu",root), tabContents = GLOBAL.Dom.getElementsByClassName("J_tab-content",root);
trigger = trigger || "click";
playTime = playTime || 3000;
var currentIndex = 0;
function showItem(n){ for(var i=0;i<tabContents.length;i++){
tabContents[i].style.display = "none";
} tabContents[n].style.display = "block";
if(currentClass){ var currentMenu =
GLOBAL.Dom.getElementsByClassName(currentClass,root)[0];
} GLOBAL.Dom.addClass(tabMenus[n],currentClass);
} if(handler){
handler(n);
} }
function autoHandler(){ currentIndex++;
if(currentIndex >= tabMenus.length){ currentIndex = 0;
} showItem(currentIndex);
} if(autoPlay){
setInterval(autoHandler,playTime);
} for(var i=0;i<tabMenus.length;i++){
tabMenus[i]._index = i;
GLOBAL.Event.on(tabMenus[i],trigger,function(){ showItem(this._index);
currentIndex = this._index;
});
} }
var tabs = GLOBAL.Dom.getElementsByClassName("J_tab");
setTab(tabs[0],null,"mouseover");
setTab(tabs[1],"tab-currentMenu",null,null,true,5000);
setTab(tabs[2],"tab-currentMenu2","mouseover",function(index){alert("您激活的是第 "+(index+1)+"个标签")});
5.3.9用 hash 对象传参
代码清单 5-101普通方式传参和 hash 对象传参
// 普通方式传参 function test(a,b,c){
var oA = a || 1, oB = b || 2, oC = c || 3;
} test(4,5,6);
test(null,7,8);
test(null,null,9);
// 用 hash 对象传参 function test2(config){
var oA = config.a || 1, oB = config.b || 2, oC = config.c || 3;
} test2({a:4,b:5,c:6});
test2({b:7,c:8});
test2({c:9});
代码清单 5-102改用 hash 对象传参
… function setTab(config){
var root = config.root;
var currentClass = config.currentClass;
var playTime = config.playTime || 3000;
var tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu",root), tabContents = GLOBAL.Dom.getElementsByClassName("J_tab-content",root);
var currentIndex = 0;
function showItem(n){ for(var i=0;i<tabContents.length;i++){
tabContents[i].style.display = "none";
} tabContents[n].style.display = "block";
if(currentClass){ var currentMenu =
GLOBAL.Dom.getElementsByClassName(currentClass,root)[0];
if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,currentClass);
} GLOBAL.Dom.addClass(tabMenus[n],currentClass);
} if(handler){
handler(n);
} }
function autoHandler(){ currentIndex++;
if(currentIndex >= tabMenus.length){ currentIndex = 0;
} showItem(currentIndex);
} if(autoPlay){
setInterval(autoHandler,playTime);
} for(var i=0;i<tabMenus.length;i++){
tabMenus[i]._index = i;
GLOBAL.Event.on(tabMenus[i],trigger,function(){ showItem(this._index);
currentIndex = this._index;
});
} }
var tabs = GLOBAL.Dom.getElementsByClassName("J_tab");
setTab({root:tabs[0],trigger:"mouseover"});
setTab({root:tabs[1],currentClass:"tab-currentMenu",autoPlay:true,playTime:5000});
setTab({root:tabs[2],currentClass:"tab-currentMenu2",trigger:"mouseover",handler:fu nction(index){alert("您激活的是第"+(index+1)+"个标签")}});
5.4面向对象编程
5.4.1面向过程编程和面向对象编程
代码清单 5-103电话本程序
// 定义电话本 1 var phonebook = [
{name:"adang",tel:"111111"}, {name:"zhangxia",tel:"222222"},
];
// 定义电话本 2 var phonebook2 = [
{name:"niaoren",tel:"111111"}, {name:"j2ee",tel:"222222"},
{name:"baobao",tel:"333333"} ];
// 查询电话 function getTel(oPhonebook,oName){
var tel = "";
for(var i=0;i<oPhonebook.length;i++){ if(oPhonebook[i].name == oName){
tel = oPhonebook[i].tel;
break;
} }
return tel;
}
// 添加记录 function addItem(oPhonebook,oName,oTel){
oPhonebook.push({name:oName,tel:oTel});
}
// 删除记录 function removeItem(oPhonebook,oName){
var n;
for(var i=0;i<oPhonebook.length;i++){ if(oPhonebook[i].name == oName){
n = i;
break;
} }
if(n != undefined){ oPhonebook.splice(n,1);
} }
// 从电话本 1 中查询”niaoren”的电话 var str = getTel(phonebook,"niaoren");
alert(str);// ""
// 在电话本 1 中添加”niaoren”的记录 addItem(phonebook,"niaoren","666666");
str = getTel(phonebook,"niaoren");
alert(str);// "666666"
// 在电话本 1 中删除”niaoren”的记录 removeItem(phonebook,"niaoren");
str = getTel(phonebook,"niaoren");
alert(str);// ""
// 在电话本 2 中查询”niaoren”的记录 str = getTel(phonebook2,"niaoren");
alert(str);// "111111"
var say = function(oName){ alert("I'm " + oName);
} var sleep = function(oState){
oState = "asleep"
} say(name);
sleep(state);
代码清单 5-105面向对象方式编程
var adang = { name : "adang",
state : "awake", say : function(){
alert("I'm " + this.name);
}, sleep : function(){
this.state = "asleep";
} };
adang.say();
adang.sleep();
5.4.2JavaScript 的面向对象编程
代码清单 5-106java 的类
// 定义 Animal 类 public class Animal{
String name , type = "animal";
public Animal(String a) { name = a;
} public void say(){
System.out.println("I'm a(an) " + type + " , my name is " + name);
} }
...
// 实例化 Animal 类 Animal myDog = new Animal("wangcai");
myDog.say();
代码清单 5-107JavaScript 中的类
// 函数作为普通函数 function sayHi(){
alert("hi");
} // 调用函数
sayHi();
// 函数作为类 function Animal(name){
this.name = name;
this.type = "animal";
this.say = function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
}
myDog.say();
代码清单 5-108构造函数和原型之间的引用
// 定义 Animal 类的构造函数 function Animal(){
… }
| var a = Animal.prototype; | // a指向Animal类对应的原型 |
|---|---|
| var b = a.constructor; | // b指向a对应的类的构造函数 |
| alert(b == Animal) | // true |
| 代码清单5-109 使用原型 |
// 定义 Animal 类 function Animal(){
} // 修改 Animal 类的原型
Animal.prototype = { name : "xxx",
type : "animal", say : function(){
alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 实例化 Animal 类 var myDog = new Animal();
myDog.say();// I’m a(an) animal , my name is xxx
代码清单 5-110使用原型的另一种方法
// 修改 Animal 类的原型 Animal.prototype.name = "xxx";
Animal.prototype.type = "ANIMAL";
Animal.prototype.say = function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
};
代码清单 5-111JavaScript 类的典型用法
// 定义 Animal 类 function Animal(name){
this.name = name || "xxx";
this.type = "animal";
} // 修改 Animal 类的原型
Animal.prototype = { say : function(){
alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 实例化 Animal 类 var myDog = new Animal("wangcai");
myDog.say();// I’m a(an) animal , my name is wangcai
代码清单 5-112JavaScript 中的公有和私有
// 定义 Animal 类 function Animal(name){
// 公有属性
var age = 20;
// 私有方法 var move = function(){
aler("I'm moving now");
} }
// 修改 Animal 类的原型 Animal.prototype = {
// 公有方法 say : function(){
alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 实例化 Animal 类 var myDog = new Animal("wangcai");
alert(myDog.name);// wangcai alert(myDog.age);// undefined
myDog.move();// 报错,myDog.move is not function
代码清单 5-113私有属性的作用域
// 定义 Animal 类 function Animal(name){
// 公有属性 this.name = name || "xxx";
this.type = "animal";
// 私有属性 var age = 20;
// 私有方法 var move = function(){
aler("I'm moving now");
} }
// 修改 Animal 类的原型 Animal.prototype = {
// 公有方法 say : function(){
alert("I'm a(an) " + this.type + " , my name is " + this.name + " , I'm " + age);
}, act : function(){
move();
} }
// 实例化 Animal 类 var myDog = new Animal("wangcai");
myDog.say();// 报错,age 未定义 myDog.act();// 报错,move is not defined
代码清单 5-114行为访问私有属性的方法
// 定义 Animal 类 function Animal(name){
// 公有属性 this.name = name || "xxx";
this.type = "animal";
// 私有属性 var age = 20;
// 私有方法
this.say = function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name + " , I'm
" + age);
} this.act = function(){
move();
} }
// 修改 Animal 类的原型 Animal.prototype = {
} // 实例化 Animal 类
var myDog = new Animal("wangcai");
| myDog.say(); | // I’m a(an) animal , my name is wangcai , I’m 20 |
|---|---|
| myDog.act(); | // I’m moving now |
| 代码清单5-115 | 使用命名约定来模拟“私有”属性 |
// 定义 Animal 类 function Animal(name){
// 公有属性 this.name = name || "xxx";
this.type = "animal";
// 私有属性 this._age = 20;
} // 修改 Animal 类的原型
Animal.prototype = { // _开头,私有方法
_move : function(){ alert("I'm moving now");
}, // 公有方法
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name + " , I'm
" + this._age);
}, act : function(){
this._move();
} }
// 实例化 Animal 类 var myDog = new Animal("wangcai");
| myDog.say(); | // I’m a(an) animal , my name is wangcai , I’m 20 |
|---|---|
| myDog.act(); | // I’m moving now |
| myDog._move(); | // I’m moving now (不推荐实例直接调用_move,违反命名约定) |
| alert(myDog._age); | // 20 (不推荐实例直接调用_age,违反命名约定) |
| 代码清单5-116 | 通过get和set方法访问属性 |
function Animal(name){ var name;
var type = "animal";
var _age = 20;
this.getName = function(){ return name;
} this.setName = function(o){
name = o;
} this.setType = function(o){
type = o;
} this._getAge = function(){
return _age;
} this._setAge = function(o){
_age = o;
} this.setName(name);
} Animal.prototype = {
_move : function(){ alert("I'm moving now");
}, say : function(){
alert("I'm a(an) " + this.getType() + " , my name is " + this.getName()
- " , I'm " + this._getAge());
}, act : function(){
this._move();
} }
var myDog = new Animal("wangcai");
| myDog.say(); | // I’m a(an) animal , my name is wangcai , I’m 20 |
|---|---|
| myDog.setType("dog"); | //通过set方法设置type属性的值 |
| alert(myDog.getType()); | //通过get方法获取type属性的值 |
| 代码清单5-117 通过set方法保护属性 |
function Animal(name){ var name;
var type = "animal";
var _age = 20;
this.getName = function(){ return name;
} this.setName = function(o){
if(o != "wangcai" && o != "xiaoqiang"){ alert("您设置的 name 值不合要求");
return;
} name = o;
} this.getType = function(){
return type;
} this.setType = function(o){
alert("赋值失败,Animal 类的 type 属性是只读的");
} this._getAge = function(){
return _age;
} this._setAge = function(o){
_age = o;
Animal.prototype = { _move : function(){
alert("I'm moving now");
}, say : function(){
alert("I'm a(an) " + this.getType() + " , my name is " + this.getName()
- " , I'm " + this._getAge());
}, act : function(){
this._move();
} }
var myDog = new Animal("wangcai");
| myDog.say(); | // I’m a(an) animal , my name is wangcai , I’m 20 |
|---|---|
| myDog.setName("abc"); | //您设置的name值不合要求 |
| alert(myDog.getName()); | // wangcai |
myDog.setName("xiaoqiang");
alert(myDog.getName());// xiaoqiang myDog.setType("dog");// 赋值失败,Animal 类的 type 属性是只读的
代码清单 5-118监听属性的 valueChange
function Animal(name){ var name = name;
var type = "animal";
var _age = 20;
// 添加 master 属性,默认值为 adang var master = "adang";
this.getName = function(){ return name;
} this.setName = function(o){
if(o != "wangcai" && o != "xiaoqiang"){ alert("您设置的 name 值不合要求");
return;
} name = o;
// 触发 name 属性的 valueChange 事件 this._valueChangeHandler("name");
} // master 属性的获取方法
this.getMaster = function(){ return master;
} // master 属性的设置方法
this.setMaster = function(o){ master = o;
// 触发 master 属性的 valueChange 事件 this._valueChangeHandler("master");
} this.getType = function(){
return type;
} this.setType = function(o){
alert("赋值失败,Animal 类的 type 属性是只读的");
} this._getAge = function(){
_age = o;
} }
Animal.prototype = { _move : function(){
alert("I'm moving now");
}, say : function(){
alert("I'm a(an) " + this.getType() + " , my name is " + this.getName()
- " , I'm " + this._getAge());
}, act : function(){
this._move();
}, // 公有行为,用于注册属性的 valueChange 事件
onChange : function(valueName,fun){ this["_" + valueName + "ChangeHadlers"] = this["_" + valueName +
"ChangeHadlers"] || [];
this["_" + valueName + "ChangeHadlers"].push(fun);
}, // 私有行为,属性 valueChange 的处理函数
_valueChangeHandler : function(valueName){ var o = this["_" + valueName + "ChangeHadlers"];
if(o){ for(var i=0,n=o.length;i<n;i++){
var methodName = "get" + valueName.charAt(0).toUpperCase()+valueName.slice(1);
o[i](this[methodName]());
} }
} }
var myDog = new Animal("wangcai");
// 给 myDog 注册 name 属性的 valueChange 事件 myDog.onChange("name",function(o){
// 回调函数接收新的 value 值作为参数,可以对其进行匹配 if(o == "xiaoqiang"){
alert(1);
} else { alert(2);
} });
// 给 myDog 换个新名字 xiaoqiang myDog.setName("xiaoqiang");// 1
//给 myDogg 再注册一个 name 属性的 valueChange 事件 myDog.onChange("name",function(o){
alert("my new name is " + o);
});
// 给 myDog 换个新名字 wangcai myDog.setName("wangcai");// 2, my new name is wangcai
// 给 myDog 注册 master 属性的 valueChange 事件 myDog.onChange("master",function(o){
alert("my new master is " + o);
})
// 给 MyDog 换个主人 myDog.setMaster("Yang Fuchuan");// my new master is Yang Fuchuan
alert(o + " is my new master");
})
myDog2.setMaster("Zhou Yubo");// Zhou Yubo is my new master
代码清单 5-119定义 Animal 类
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
代码清单 5-120定义 Bird 类
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 定义 Bird 类 function Bird(){
} Bird.prototype = {
}
代码清单 5-121继承构造函数中的属性和行为
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 定义 Bird 类 function Bird(name){
this.name = name;
this.type = "animal";
} Bird.prototype = {
}
代码清单 5-122改进构造函数中的继承
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 定义 Bird 类 function Bird(name){
Animal(name);
} Bird.prototype = {
}
// 实例化 Bird 对象 var myBird = new Bird("xiaocui");
alert(myBird.type);// undefined
代码清单 5-123实际效果
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 定义 Bird 类 function Bird(name){
window.name = name;
window.type = "animal";
} Bird.prototype = {
}
// 实例化 Bird 对象 var myBird = new Bird("xiaocui");
alert(myBird.type);// undefined alert(type);// animal(window.type 可省略写成 type)
代码清单 5-124使用 call 方法指定 this 指向
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
}
} }
// 定义 Bird 类 function Bird(name){
Animal.call(this,name);
} Bird.prototype = {
}
// 实例化 Bird 对象 var myBird = new Bird("xiaocui");
alert(myBird.type);// animal
代码清单 5-125原型的继承
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 定义 Bird 类 function Bird(name){
Animal.call(this,name);
} Bird.prototype = Animal.prototype;
// 实例化 Bird 对象 var myBird = new Bird("xiaocui");
myBird.say();// I'm a(an) animal , my name is xiao cui
代码清单 5-126添加 fly 行为
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 定义 Bird 类 function Bird(name){
Animal.call(this,name);
} Bird.prototype = Animal.prototype;
Bird.prototype.fly = function(){ alert("I'm flying");
}
myBird.say();// I'm a(an) animal , my name is xiao cui myBird.fly();// I’m flying
var myDog = new Animal("wangcai");
myDog.fly();// I’m flying
代码清单 5-127传值与传址
var a = 10;// 基本数据类型
| var b = a; | //将变量a保存的值复制一份,传给变量b,a和b各保存一份数据 |
|---|---|
| var c = [1,2,3]; | //复杂数据类型 |
| var d = c; | //将变量c指向的数据的内存地址传给变量d,c和d指向同一份数据 |
b++;
d.push(4);
alert(a);// 10
| alert(b); | // 11 | 变量b保存的数据更改不会影响到变量a |
|---|---|---|
| alert(c); | // 1,2,3,4 | 变量c和d指向同一份数据,数据更改会互相影响 |
| alert(d); | // 1,2,3,4 | |
| 代码清单5-128 | 对复杂数据类型进行传值 |
var a = [1,2,3] , b = {name:"adang",sex:"male",tel:"1234567"};
var c = [] , d = {};
for(var p in a){ c[p] = a[p];
} for(var p in b){
d[p] = b[p];
} c.push("4");
d.email = "xxx@gmail.com";
alert(a);// 1,2,3 alert(c);// 1,2,3,4
alert(b.email);// undefined alert(d.email);// xxx@gmail.com
代码清单 5-129数组传值的简单方法
var a = [1,2,3];
var b = a.slice() , c = a.concat();
b.pop();
c.push(4);
alert(a);// 1,2,3 alert(b);// 1,2
alert(c);// 1,2,3,4
代码清单 5-130改进原型继承
// 定义 Animal 类 function Animal(name){
this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
// 定义 Bird 类 function Bird(name){
Bird.prototype.constructor = Bird;
Bird.prototype.fly = function(){ alert("I'm flying");
}
// 实例化 Bird 对象 var myBird = new Bird("xiaocui");
myBird.say();// I'm a(an) animal , my name is xiao cui myBird.fly();// I’m flying
var myDog = new Animal("wangcai");
myDog.fly();// 报错,myDog.fly is not a function
代码清单 5-131定义 extend 函数
function extend(subClass,superClass){ var F = function(){};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor){ superClass.prototype.constructor = superClass;
} }
function Animal(name){ this.name = name;
this.type = "animal";
} Animal.prototype = {
say : function(){ alert("I'm a(an) " + this.type + " , my name is " + this.name);
} }
function Bird(name){ this.constructor.superclass.constructor.apply(this,arguments);
this.type = "bird"
} extend(Bird,Animal);
Bird.prototype.fly = function(){ alert("I'm flying");
} var canary = new Bird("xiaocui");
canary.say();// I’m a(an) bird , my name is xiaocui canary.fly();// I’m flying
5.4.3用面向对象方式重写代码
代码清单 5-132用面向对象方式重写电话本程序
// 定义电话本管理类 function PhonebookManager(){
this._phonebook = null;
} PhonebookManager.prototype = {
// 查询电话 getTel : function(){
}, // 删除记录
removeItem : function(){
} }
代码清单 5-133定义行为的参数
// 定义电话本管理类 function PhonebookManager(o){
this._phonebook = o;
} PhonebookManager.prototype = {
// 查询电话 getTel : function(oName){
}, // 添加记录
addItem : function(oName,oTel){
}, // 删除记录
removeItem : function(oName){
} }
代码清单 5-134编写具体的行为代码
// 定义电话本管理类 function PhonebookManager(o){
this._phonebook = o;
} PhonebookManager.prototype = {
// 查询电话 getTel : function(oName){
var tel = "";
for(var i=0;i<this._phonebook.length;i++){ if(this._phonebook[i].name == oName){
tel = this._phonebook[i].tel;
break;
} }
return tel;
}, // 添加记录
addItem : function(oName,oTel){ this._phonebook.push({name:oName,tel:oTel});
}, // 删除记录
removeItem : function(oName){ var n;
for(var i=0;i<this._phonebook.length;i++){ if(this._phonebook[i].name == oName){
n = i;
break;
}
} }
}
代码清单 5-135使用面向对象的电话本程序
// 实例化两个电话本管理对象 var myPhonebookManager = new PhonebookManager([
{name:"adang",tel:"111111"}, {name:"zhangxia",tel:"222222"},
{name:"yangfuchuan",tel:"333333"}, {name:"qiaojiwu",tel:"444444"},
{name:"zhouyubo",tel:"555555"} ]),
myPhonebookManager2 = new PhonebookManager([ {name:"niaoren",tel:"111111"},
{name:"j2ee",tel:"222222"}, {name:"baobao",tel:"333333"}
]);
// 从电话本 1 中查询”niaoren”的电话 var str = myPhonebookManager.getTel("niaoren");
alert(str);// ""
// 在电话本 1 中添加”niaoren”的记录 myPhonebookManager.addItem("niaoren","666666");
str = myPhonebookManager.getTel("niaoren");
alert(str);// "666666"
// 在电话本 1 中删除”niaoren”的记录 myPhonebookManager.removeItem("niaoren");
str = myPhonebookManager.getTel("niaoren");
alert(str);// ""
// 在电话本 2 中查询”niaoren”的记录 str = myPhonebookManager2.getTel("niaoren");
alert(str);// "111111"
代码清单 5-136用面向对象方式重构 Tab
var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
GLOBAL.namespace("Dom");
GLOBAL.Dom.getElementsByClassName = function(str,root,tag){ if(root){
root = typeof root == "string" ? document.getElementById(root) : root;
} else { root = document.body;
} tag = tag || "*";
var els = root.getElementsByTagName(tag),arr = [];
for(var i=0,n=els.length;i<n;i++){
break;
} }
} return arr;
} 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),"");
} GLOBAL.namespace("Event");
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);
} }
function Tab(config){ this._root = config.root;
this._currentClass = config.currentClass;
var trigger = config.trigger || "click";
this._handler = config.handler;
var autoPlay = config.autoPlay;
var playTime = config.playTime || 3000;
this._tabMenus = GLOBAL.Dom.getElementsByClassName("J_tab-menu",this._root);
this._tabContents = GLOBAL.Dom.getElementsByClassName("J_tab-content",this._root);
this.currentIndex = 0;
var This = this;
if(autoPlay){ setInterval(function(){This._autoHandler()},playTime);
} for(var i=0;i<this._tabMenus.length;i++){
this._tabMenus[i]._index = i;
GLOBAL.Event.on(this._tabMenus[i],trigger,function(){ This.showItem(this._index);
this.currentIndex = this._index;
});
} }
Tab.prototype = { showItem : function(n){
for(var i=0;i<this._tabContents.length;i++){ this._tabContents[i].style.display = "none";
}
GLOBAL.Dom.getElementsByClassName(this._currentClass,this._root)[0];
if(currentMenu){ GLOBAL.Dom.removeClass(currentMenu,this._currentClass);
} GLOBAL.Dom.addClass(this._tabMenus[n],this._currentClass);
} if(this._handler){
this._handler(n);
} },
_autoHandler : function(){ this.currentIndex++;
if(this.currentIndex >= 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.1prototype 和内置类
代码清单 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;i<n;i++){
fun(this[i],i);
} }
Array.prototype.clone = function(){ var o = [];
this.each(function(v,k){ o[k] = v;
});
return o;
} Array.prototype.map = function(fun){
});
return o;
} //因为 IE 中 delete 是保留字,所以方法名改用 Delete
Array.prototype.Delete = function(a){ var o = this.clone();
for(var i=o.length,n=0;i>n;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";
} }
代码清单 5-141重写属性
Array.prototype.length = 1;
String.prototype.length = 1;
代码清单 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;i<n;i++){ fun(o[i],i);
} }
} var a = new myArray([1,2,3]),str = "";
a.each(function(v,k){ str += k + " : " + v + "\n";
});
alert(str);// 0 : 1 1 : 2 2 : 3
5.5.2标签的自定义属性
代码清单 5-144html 标签和 js 的映射
<a id="a" class="b" title="" href="http://www.adanghome.com"
onclick="alert(this.href);return false;">my blog</a> <script type="text/JavaScript">
var node = document.getElementById("a");
alert(typeof node);// object </script>
代码清单 5-145在 JavaScript 中获得 DOM 节点对象的属性
<a id="a" class="b" title="" href="http://www.adanghome.com"
onclick="alert(this.href);return false;">my blog</a> <script type="text/JavaScript">
var node = document.getElementById("a");
alert(node.getAttribute("id"));// a alert(node.id)// a
<a id="a" class="b" title="我的博客" href="http://www.adanghome.com"
onclick="alert(this.href);return false;">my blog</a> <script type="text/JavaScript">
var node = document.getElementById("a");
alert(node.getAttribute("id"));
/* IE 和 Firefox : a
*/
alert(node.getAttribute("class"));
/* IE: null
Firefox : b */
alert(node.getAttribute("className"));
/* IE: b
Firefox : null */
alert(node.getAttribute("title"));
/* IE 和 Firefox : 我的博客
*/
alert(node.getAttribute("href"));
/* IE 和 Firefox : http://www.adanghome.com
*/
alert(node.getAttribute("onclick"));
/* IE: function onclick(){
alert(this.href);return false;
} Firefox : alert(this.href);return false;
*/
alert(node.getAttribute("innerHTML"));
/* IE: my blog
Firefox : null */
alert(node.id);
/* IE 和 Firefox : a
*/
alert(node.className);
/* IE 和 Firefox : b
*/
alert(node.title);
alert(node.href);
/* IE 和 Firefox : http://www.adanghome.com
*/
alert(node.onclick);
/* IE: function onclick(){
alert(this.href);return false;
} Firefox : function onclick(event){
alert(this.href);
return false;
} */
alert(node.innerHTML));
/* IE 和 Firefox : my blog
*/
代码清单 5-147JavaScript 和 html 间的映射
<style type="text/CSS"> .red{color:red;}
</style> <span id="a">hello world</span>
<script type="text/JavaScript"> var node = document.getElementById("a");
node.className = "red";
</script>
代码清单 5-148自定义属性的获取
<a id="a" href="http://www.adanghome.com" blogName="阿当的博客" blogType="前端开发">my blog</a>
<script type="text/JavaScript"> var node = document.getElementById("a");
alert(node.blogName);
/* IE: 阿当的博客
Firefox : undefined */
alert(node.blogType);
/* IE: 前端开发
Firefox : undefined */
alert(node.getAttribute("blogName"));
/* IE 和 Firefox : 阿当的博客
*/
alert(node.getAttribute("blogType"));
/*
代码清单 5-149自定义属性的反序列化
<a id="a" href="http://www.adanghome.com" blogInfo="{name:'阿当的博客',type:'前端开发'}">my blog</a>
<script type="text/JavaScript"> var node = document.getElementById("a");
var info = node.getAttribute("blogInfo");
| alert(typeof info); | // string |
|---|---|
| alert(info.name); | // undefined |
| alert(info.type); | // undefined |
info = eval("("+info+")");
| alert(typeof info); | // object |
|---|---|
| alert(info.name); | //阿当的博客 |
| alert(info.type); | //前端开发 |
</script>
5.5.3标签的内联事件和 event 对象
代码清单 5-150简单的点击事件
<input type="button" id="btn" value="click me" />
<script type="text/JavaScript"> document.getElementById("btn").onclick = function(){
alert(arguments.length);
};
</script>
代码清单 5-151内联事件中的点击事件
<input type="button" id="btn" value="click me" onclick = "handler()" />
<script type="text/JavaScript"> function handler(){
alert(arguments.length);
};
</script>
代码清单 5-152替换可能一
btn.onclick = handler;
function handler(){ alert(arguments.length);
}
代码清单 5-153替换可能二
btn.onclick = function(){ handler();
} function handler(){
alert(arguments.length);
}
代码清单 5-154内联事件和参数
<input type="button" id="btn" value="click me" onclick = "alert(arguments[0].type)"
/>
<script type="text/JavaScript"> document.getElementById("btn").onclick = function(e){
e = window.event || e;//e 兼容 IE 和 Firefox,指向 event 对象 };
</script>
代码清单 5-156在内联事件中兼容 event 对象
<input type="button" id="btn" value="click me" onclick="alert(event.type);" />
代码清单 5-157内联事件的使用
//只弹出 1 <input type="button" id="btn" value="click me"
onclick="alert(1);//alert(2);alert(3);" />
//弹出 1 和 3 <input type="button" id="btn" value="click me"
onclick="alert(1);/*alert(2);*/alert(3);" />
//弹出“string”
<input type="button" id="btn" value="click me" onclick="var a='abc';alert(typeof a);"/>
代码清单 5-158在两处同时监听事件
<input type="button" id="btn" value="click me" onclick="alert(123);" />
<script type="text/JavaScript"> document.getElementById("btn").onclick = function(){
alert(456);
};
</script>
代码清单 5-159等同效果
<input type="button" id="btn" value="click me" />
<script type="text/JavaScript"> document.getElementById("btn").onclick = function(){
alert(123);
};
document.getElementById("btn").onclick = function(){ alert(456);
};
</script>
代码清单 5-160改进方案,同时监听两处事件
<input type="button" id="btn" value="click me" onclick="alert(123);" />
<script type="text/JavaScript"> function handler(){
alert(456);
} if(document.all){
btn.attachEvent("onclick",handler);
} else { btn.addEventListener("click",handler,false);
} </script>
5.5.4利用事件冒泡机制
代码清单 5-161打分程序
<!—- 编写 rate 相关的 html 结构 --> <h1>阿当饭店</h1>
<p>卫生:<p> <p class="J_rate">
<img src="star.gif" title="很烂" /> <img src="star.gif" title="一般" />
<img src="star.gif" title="还好" /> <img src="star.gif" title="较好" />
<img src="star.gif" title="很好" /> </p>
<p>价格:<p> <p class="J_rate">
<img src="star.gif" title="很烂" /> <img src="star.gif" title="一般" />
<img src="star.gif" title="还好" /> <img src="star.gif" title="较好" />
<img src="star.gif" title="很好" /></p> <p>味道:<p>
<p class="J_rate"> <img src="star.gif" title="很烂" />
<img src="star.gif" title="一般" /> <img src="star.gif" title="还好" />
<img src="star.gif" title="较好" /> <img src="star.gif" title="很好" />
</p> <script type="text/JavaScript">
// 封装 DOM、Event 接口 var GLOBAL = {};
GLOBAL.namespace = function(str){ var arr = str.split("."),o = GLOBAL;
for (i=(arr[0] == "GLOBAL") ? 1 : 0; i<arr.length; i++) { o[arr[i]]=o[arr[i]] || {};
o=o[arr[i]];
} }
GLOBAL.namespace("Dom");
GLOBAL.Dom.getElementsByClassName = function(str,root,tag){ if(root){
root = typeof root == "string" ?
document.getElementById(root) : root;
} else { root = document.body;
} tag = tag || "*";
var els = root.getElementsByTagName(tag),arr = [];
for(var i=0,n=els.length;i<n;i++){ for(var j=0,k=els[i].className.split("
"),l=k.length;j<l;j++){ if(k[j] == str){
arr.push(els[i]);
break;
} }
} return arr;
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)
;
} }
// 定义 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<n;i++){ items[i].index = i;
GLOBAL.Event.on(items[i],"mouseover",function(){ if(rateFlag) return;
for(var j=0;j<n;j++){ if(j<=this.index){
items[j].src = imgs[1];
} else { items[j].src = imgs[0];
} }
});
GLOBAL.Event.on(items[i],"mouseout",function(){ if(rateFlag) return;
for(var j=0;j<n;j++){ items[j].src = imgs[0];
} });
GLOBAL.Event.on(items[i],"click",function(){ if(rateFlag) return;
rateFlag = true;
alert("您打了"+(this.index+1)+"分");
});
} }
// 实例化 Rate 类 var rateNodes = GLOBAL.Dom.getElementsByClassName("J_rate");
for(var i=0,n=rateNodes.length;i<n;i++){ new Rate(rateNodes[i]);
} </script>
代码清单 5-162等同效果
<p class="J_rate"> <img src="star.gif" title="很烂" onmouseover="…" onmouseout="…" onclick="…" />
<img src="star.gif" title="一般" onmouseover="…" onmouseout="…" onclick="…" />
</p>
代码清单 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<n;i++){ items[i].index = i;
} GLOBAL.Event.on(root,"mouseover",function(e){
if(rateFlag) return;
var target = e.target || e.srcElement;
if(target.tagName.toLowerCase() != "img") return;
for(var i=0;i<n;i++){ if(i<=target.index){
items[i].src = imgs[1];
} else { items[i].src = imgs[0];
} }
});
GLOBAL.Event.on(root,"mouseout",function(e){ if(rateFlag) return;
var target = e.target || e.srcElement;
for(var i=0,n=items.length;i<n;i++){ items[i].src = imgs[0];
} });
GLOBAL.Event.on(root,"click",function(e){ if(rateFlag) return;
rateFlag = true;
var target = e.target || e.srcElement;
alert("您打了"+(target.index+1)+"分");
});
}
代码清单 5-164等同效果
<p class="J_rate" onmouseover="…" onmouseout="…" onclick="…"> <img src="star.gif" title="很烂" />
<img src="star.gif" title="一般" /> <img src="star.gif" title="还好" />
<img src="star.gif" title="较好" /> <img src="star.gif" title="很好" />
</p>
5.5.5改变 DOM 样式的三种方式
代码清单 5-165改变 DOM 节点样式的方法一
<span id="test">hello world</span> <script type="text/JavaScript">
var node = document.getElementById("test");
node.style.color = "red";
<span id="test" style="color:red">hello world</span>
代码清单 5-167用方法一改变多个样式
<span id="test">hello world</span> <script type="text/JavaScript">
var node = document.getElementById("test");
node.style.color = "red";
node.style.backgroundColor = "black";
node.style.fontSize = "40px";
node.style.fontWeight = "bold";
</script>
代码清单 5-168等同效果
<span id="test"
style="color:red;background-color:black;font-size:40px;font-weight:bold">hello world</span>
代码清单 5-169改变 DOM 节点样式的方法二
<style type="text/CSS"> .testStyle{color:red;background-color:black;font-size:40px;font-weight:bold;}
</style> <span id="test">hello world</span>
<script type="text/JavaScript"> var node = document.getElementById("test");
node.className = "testStyle";
</script>
代码清单 5-170等同效果
<style type="text/CSS"> .testStyle{color:red;background-color:black;font-size:40px;font-weight:bold;}
</style> <span id="test" class="testStyle">hello world</span>
代码清单 5-171需设置样式的 DOM 节点
<span id="test">hello world</span> <span>aaaaaa</span>
<span>bbbbbb</span> <span>cccccc</span>
代码清单 5-172等同效果一
<span id="test" style="font-size:40px;background:#000;color:red">hello world</span> <span style="font-size:40px;background:#000;color:#fff">aaaaaa</span>
<span style="font-size:40px;background:#000;color:#fff">bbbbbb</span> <span style="font-size:40px;background:#000;color:#fff">cccccc</span>
代码清单 5-173等同效果二
<style type="text/CSS"> .testStyle{font-size:40px;background:#000;color:#fff}
#test{color:red} </style>
<span id="test" class="testStyle">hello world</span> <span class="testStyle">aaaaaa</span>
<span class="testStyle">bbbbbb</span> <span class="testStyle">cccccc</span>
代码清单 5-174改变 DOM 节点样式的方法三
<span>cccccc</span> <script type="text/JavaScript">
function addStyleNode(str){ var styleNode = document.createElement("style");
styleNode.type = "text/CSS";
if(styleNode.styleSheet){ styleNode.styleSheet.cssText = str;
} else { styleNode.innerHTML = str;
} document.getElementsByTagName("head")[0].appendChild(styleNode);
} addStyleNode("span{font-size:40px;background:#000;color:#fff}
#test{color:red}");
</script>
代码清单 5-175等同效果
<style type="text/CSS"> span{font-size:40px;background:#000;color:#fff}
#test{color:red} </style>
<span id="test">hello world</span> <span>aaaaaa</span>
<span>bbbbbb</span> <span>cccccc</span>
附录前端规范
附录 A 写在规则前面的话
附录 B 命名规则
html:
<ul class=”textList”> <li class=”textList_firstItem”>1)XXXXXXXXXXXXXX</li>
<li>2)XXXXXXXXXXXXXX</li> <li>3)XXXXXXXXXXXXXX</li>
</u1>
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 规范
<!--头部开始{--> <div class="head">
<div class="header clearfix"> <h1 class="fr">阿当制作</h1>
<h2 class="fb fl">阿当测试站点<span class="gray fn">的页面管理模式</span></h2> <input type="button" value="完成并退出" class="ml50 fl" />
</div> </div>
<!--}头部结束-->
附录 F CSS 规范
html:
<p>12345</p> <ul class="textList">
<li>1)XXXXXXXXXXX</li> <li>2)XXXXXXXXXXX</li>
</ul> <p>abcde</p>
<ul class="textList2"> <li>1)XXXXXXXXXXX</li>
<li>2)XXXXXXXXXXX</li> </ul>
CSS:
.textList,.textList2{margin-top:10px;XXXXXXXXXXXXXX} .textList2{margin-top:20px;}
X
=====================================================
html:
<p>12345</p> <ul class="textList marginTop10">
<li>1)XXXXXXXXXXX</li> <li>2)XXXXXXXXXXX</li>
</ul> <p>abcde</p>
<ul class="textList marginTop20"> <li>1)XXXXXXXXXXX</li>
<li>2)XXXXXXXXXXX</li> </ul>
CSS:
.textList{XXXXXXXXXXXXXX} .marginTop10{margin-top:10px;}
.marginTop20{margin-top:20px;} V
<p>XXXXXXXXXXXXX</p> <p class="marginTop10 marginBottom10">XXXXXXXXXXXX</p>
<p>XXXXXXXXXXXXX</p>
<p>XXXXXXXXXXXXX</p> <p class="marginTop10">XXXXXXXXXXXXX</p>
<p class="marginTop10">XXXXXXXXXXXXX</p> V
.menu{margin:0;float:left;font-weight:bold;}V .menu{
margin:0;
float:left;
font-weight:bold;
}X