一、JavaScript简史
XHTML DHTML CSS DOM
二、JavaScript语法
使用方法:1,插入<head>部分
2,独立的文件
变量区分大小写,不允许包含空格和标点符号
数据类型:
字符串、布尔值、数组、关联数组
变量的作用域:
var
对象:
内建对象、宿主对象、用户定义对象、document对象
三、DOM
节点类型:
元素节点、属性节点、文本节点
方法:
getElementById、getElementsByTagName、getAttribute、setAttribute
属性:
childNodes、nodeValue、firstChild、lastChild、nextSibling、prevSibling、parentNode
四、JavaScript编程原则和良好习惯
预留退路(没有javascript的情况)
弹窗window.open(url,name,features)、伪协议javascript:popUp(url)、内嵌的事件处理函数onclick
分离JavaScript(结构、表现与行为,即MVC)
1,window.onLoad=function(){
function a();
function b();
};
2,window.addLoadEvent(func){
var oldonload = window.onload;
if(typeof window.onload != ‘function’){
window.onload = func;
}else{
window.onload = funtion(){
oldonload();
func();
}
}
}
向后兼容(兼容老版本浏览器)
if(method) return false;
五、动态创建HTML内容
write()、writeln()
innerHTML属性
createElement()
createTextNode()
appendChild()
insertBefore()
var para = document.createElement(‘P’);
var txt = document.createTextNode(“hello,world”);
para.appendChild(txt);
var testDiv = document.getElementById(‘div’);
testDiv.appendChild(para);
var testIns = document.createElement(‘go’);
testDiv.insertBefore(testIns,para);
insertAfter()的实现原理:
判断目标元素是否为其父元素的最后一个,是则使用append方法,否则使用insertBefore(newElement,targetElement.nextSibling)。
六、充实文档的内容
for(var in array)
七、CSS-DOM
style属性是一个对象:
element.style.property(body.style.backgroundColor = “blue”);
它只能查询内嵌在html内容里的样式信息
P、.、#
鼠标划过变样式:onmouseover
八、JavaScript实现动画效果
var variable= setTimeout(“function”,interval);
clearTimeout(variable);
nodeType、nodeName、nodeValue(返回属性或文本内容)
reference = document.removeChild(node)
reference = document.replaceChild(newChild,oldChild)
booleanValue = element.hasChildNodes;
第一章 JavaScript实现
JavaScript由三个部分组成:ECMAScript、DOM、BOM。
DOM级别:
第二章 在HTML中使用JavaScript
定义变量而未赋值的话,会保存一个特殊值——undefined。
ECMAScript中有5种简单数据值类型:Undefined、Null、Bollean、Number和String。还有一种复杂类型——Object(本质上是由一组无需的名值对组成的)
typeof操作符。返回值为字符串:“undefined”、“boolean”、“string”、“number”、“object”、“function”。
进行算术计算时,八进制和十六进制数最终转成十进制。
数值范围:Number.MIN_VALUE; Number.MAX_VALUE
NaN,一个特殊数值,表示本来要返回数值的操作数未返回数值。通过isNaN()函数测试返回布尔值。传入参数若可转为数值,则返回false。
数值转换:Number()——可用于任何类型。parseInt()和parseFloat()——仅用于字符串。
转义序列:\n换行;\t制表;\b空格;\r回车;\f进纸;\\斜杠;\”单引号;\”双引号;\xnn以十六进制代码nn表示的一个字符(n为0到F)\unnn以十六进制代码nnn表示的一个unicode字符。
Object类型的实例都具有下列属性和方法:
□ constructor属性:保存着用于创建当前对象的函数。
□ hasOwnProperty(propertyName)——用于检查给定的属性在当前对象实例中(而非实例的原型中)是否存在。
□ isPrototypeof(object)——用于检查传入对象是否是另一个对象的原型。
□ propertyIsEnumerable(propertyName)——用于检查给定属性是否能够使用for-in语句。
□ toString():返回对象的字符串表示。
□ valueof():返回对象的字符串、数值或布尔值表示。
布尔操作符:
□ 逻辑非(!):所有类型自动调用Boolean()再进行逻辑非操作,返回布尔值。
□ 逻辑与(&&),逻辑或(||):不一定返回布尔值。
②逻辑与(&&),在有一个操作数不是布尔值的情况下,逻辑与操作符就不一定返回布尔值:
□ 如果第一个操作数是对象,则返回第二个操作数。
□ 如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象。
□ 如果两个操作数都是对象,则返回第二个操作数。
□ 如果有一个操作数是null,则返回null。
□ 如果有一个操作数是NaN,则返回NaN。
□ 如果有一个操作数是undefined则返回undefined。
③逻辑或(||),如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值:
□ 如果第一个操作数是对象,则返回第一个操作数。
□ 如果第一个操作数求值为false,则返回第二个操作数。
□ 如果两个操作数都是对象,则返回第一个操作数。
□ 如果两个操作数都是null,返回null
□ 如果两都为undefined,返undefined。
□ 如果两都为NaN,返NaN
②全相等和不全相等(仅比较而不转换)“===”“!==”
由于ECMAScript中不存在块级作用域,因此循环内部定义的变量可以在外部访问到。
ECMAScript函数的参数:
ECMAScript中的参数在内部是用个数组表示的。解析器不在乎传入多少个参数,无论声明时定义了多少。
有声明但无参数传入,均赋值为undefined。
函数内部可以用arguments[i]调用参数。
ECMAScript所有参数传递都是值传递,无引用传递。
ECMAScript没有重载,通过传入函数中参数类型和数量并作不同的反应,可模仿方法的重载。
第四章 变量、作用域和内存问题
typeof操作符一般用于检测基本数据类型值,String、Number、Boolean、undefined。但检测引用类型时不给力,只能返回object,无法判断是什么类型的对象。
instanceof操作符:result = variable
垃圾收集实现方法
□ 标记清除:标记进入、退出环境状态,以完成内存清除。
◇ 各浏览器js引擎均以此为垃圾收集引擎。
□ 引用计数:跟踪记录每个值被引用的次数。
◇ 易导致循环引用,使得无法清除无用内存。IE中非原生JS对象和BOM、DOM(COM对象)其垃圾收集为引用计数。
管理内存
解除引用:当数据不再有用,通过将其值设置为null来解放引用。
第五章 引用类型
ECMAScript中引用类型是一种数据结构,将数据和功能组织在一起。类似与其他语言的“类”。
Object类型:
创建方法:
□ new操作符+构造函数
□ 对象字面量 var a = {},即创建了object对象。
②对象属性可通过点号语法和方括号语法访问。
□ person.name
□ person[“name”],此方法适用于用变量访问属性时使用。
Array类型
①ECMAScript数组的每一项可以保存任何类型的数据。
②数组大小是可动态调整的,可随着数据的添加自动增加容纳新增数据。数组的length属性可读可写。
③转换方法:toLocaleString()、toString()和valueOf(),join()
其他方法:push,pop,shift,unshift,reverse,sort,concat,slice(开始,结束),splice(开始,项数,元素,元素),substr,substring,indexOf,lastIndexOf,toLowerCase,toUpperCase,toLocalLowerCase,
RegExp类型
①创建正则表达式: var expression = / pattern / flags;
□ 其中的模式(pattern)部分可以是任何简单或复杂的正则表达式。
□ flags,用以标明正则表达式的行为。
◇ g-全局(global)模式,即应用于所有字符串,非匹配一项即停。
◇ i-不区分大小写(case-insensitive)模式。
◇m-多行(multiline)模式,到一行末尾会查下一行。
△可用构造函数创建正则:var a = new RegExp(“[bc]at”,”i”); //这种方法需要对字符进行双重转义。
□ exec(),接受一个参数,即要应用模式的字符串。没匹配则返回null,有匹配则返回带属性index、input的数组。
◇ index:匹配项在字符串中位置
◇ input:表示应用正则表达式的字符串
◇ 数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串。
Number类型(基本包转类型,不建议实例化)
①valueOf()、toLocaleString()、toString()方法。基本数据类型已提及。
②toFix(num):以指定小数位返回数值的字符串表示。
③toExponential(num):返回以指数(e)表示数值的字符串,参数指定输出结果中的小数位数。
④toPrecision(num):以合适方式返回数值字符串。参数指定表示数值的所有数字的位数(不含指数部分)。
□ test(),接受一个字符串,与模式匹配返true,否则false
⑦字符串的模式匹配方法:
□ match():本质上与RegExp的exec()相同。接受一个参数,可以是一个正则表达式,可以是一个RegExp对象。返回一个数组。
□ search():从头开始向后查找,返回第一个匹配索引。
□ replace():第一个参数为要替换的值,可是字符串或正则。
□ split():基于指定的分隔符讲一个字符串分割成多个字符串,结果一数组形式返回。第一个参数是分隔符,可是字符串或一个RegExp对象。第二个参数可选,指定数组大小。
⑧localeCompare(),比较字符串返回下面值:
□ 字符串在字母表中排在参数前,返回负数(通常为-1)。
□ 相等则返回0
□ 排在后面返回正数(通常为1)
⑨fromCharCode():接受一或多个字符编码,然后将它们转换成一个字符串。
第六章 面向对象的程序设计
工厂模式、构造函数模式、原型模式、动态原型模式、寄生构造函数模式、稳妥构造函数模式
继承
第七章 匿名函数——Lambda
第一章:从网站重构说起
2.打造高品质的前端代码,提高代码的可维护性——
1>精简:可以让文件变小,有利于客户端快速下载;
2>重用:可以让代码更易于精简,同时有助于提升开发速度;
3>有序:可以让我们更清晰地组织代码,使代码更易于维护,有效应对变化。
第二章:团队合作
第三章:高质量的HTML
2.常见模块
1>标题内容模块
2>表单模块
3>表格模块
3.其他
1>尽可能少地使用无语义标签div和span
2>不使用纯样式标签(如b/font/u等)
第四章:高质量的CSS
1.怪异模式和DTD
1>为了确保向后兼容,浏览器厂商发明了标准模式和怪异模式这两种方法来解析网页
标准模式:浏览器根据规范表现页面
怪异模式:通常模拟老式浏览器(比如IE4和Netscape Navigator 4)的行为以防止老站点无法工作,在该模式下
(1)width包含border和padding
(2)margin: 0 auto;无法达到居中效果
可用这两点来判断浏览器是否是处于怪异模式(尤其是针对IE)
2>DTD:Document Type Definition,即文档类型定义。DTD是一种保证HTML文档格式正确的有效方法,
可以通过比较HTML文档和DTD文件来看文档是否符合规范,以及元素和标签使用是否正确。
一个DTD文档包含元素的定义规则、元素间关系的定义规则、元素可使用的属性、可使用的实体或符号规则。
如果漏写DTD声明,Chrome/Firfox/Safari/Opera仍然会按照标准模式来解析网页,但在IE中(IE6/7/8)就会触发怪异模式。
/
/
2.如何组织CSS
将网站内的所有样式,按照职能分成3大类:base、common、page
1>这三者是层叠结构
2>base层:提供CSS reset功能和力度最小的通用原子类。
这一层与具体UI无关,无论何种风格的设计都可以引用它,所以base层要力求精简和通用。
3>common层:位于中间,提供组件级的CSS类。
将页面内的元素拆分成一小块一小块功能和样式相对独立的小“模块”;
common是网站级的,不同的网站有不同的common层
4>page层:非高度重用的模块
page层位于最高层,提供页面级的样式。
/
/
3.模块化CSS
1>单一职责
(1)模块与模块之间尽量不要包含相同的部分,如果有相同部分,应将它们提取出来,拆分成一个独立的模块;
(2)模块应在保证数量尽可能少的原则下,做到尽可能简单,以提高重用性。
2>命名空间
css命名空间的概念
<div class=”box”>
<div class=”box-hd”></div>
<div class=”box-bd”></div>
<div class=”box-ft”></div>
</div>
可以将这里的box命名理解为一个类的类名称(也就是模块名称),而这里的hd/bd/ft正是box里面的(私有)变量,
box内部样式的修改并不会影响box模块外的样式,可以理解为这里的box起到了命名空间的作用。
3>多用组合、少用继承
(1)能够大大减少类的数量,提高了可维护性;
(2)使类的职责更单一,弹性更强,增加了类的重用性,提高了开发效率。
当然,这种方式会让HTML标签看起来过于臃肿,但是它带来的好处确实不容忽视的,推荐挂多了class的方式
4>处理上下margin
如果不确定模块的上下margin特别稳定,最好不要将它写到模块的类里,而是使用类的组合,
单独为上下margin挂用于边距的原子类。模块最好不要混用margin-top和margin-bottom,
统一使用margin-top或margin-bottom。
/
/
4.常见问题
1>为了保证样式容易被覆盖,提高可维护性,CSS选择符需保证权重尽可能低。
2>CSS sprite
在网站流量限制及维护性上找到一个平衡点
3>CSS编码风格(一行式、多行式)
笔者倾向于一行式,个人倾向于多行式
4>class和id
尽量使用class,少用id
5>CSS hack(IE条件注释法、选择符前缀法、样式属性前缀法)
个人倾向于样式属性前缀法
6>display: inline-block和haslayout
能够触发IE6/IE7(其本身并不支持display: inline-block)行内元素的haslayout.
7>relative、absolute、float
(1)position: relative;会保留自己在z-index:0层的占位,
其left/right/top/bottom值是相对于自己在z-index:0层的位置
(2)position: absolute;会完全脱离文档流,不再在z-index:0层保留占位符,
其left/right/top/bottom值是相对于自己最近的一个设置了position: relative;或
postion: absolute;的祖先元素,如果发现没有,那么就相对于body元素了。
(3)float: left/right;属性不会让元素“上浮”到另一个z-index层,它仍然让元素在z-index层排列,
float会改变正常的文档流排列,影响到周围元素。
8>水平居中和垂直居中
9>网格布局(grid-xxx-xx、layout-xxx-xx、content-xxx-xx)
10>z-index和IE6下的select元素
/
第五章:高质量的JavaScript
/
1.防止JS冲突
1>用匿名函数(自执行)将脚本抱起来,可以有效控制全局变量,避免冲突隐患。
2>让JS不产生冲突,需要避免全局变量的泛滥,合理使用命名空间以及为代码添加必要的注释。
2.JS分层思想
1>base层
位于三层中的最底端,具有两个职责。其一,封装不同浏览器下JavaScript的差异,提供统一的接口。
其二,扩展JavaScript语言底层提供的接口,让它提供更多更为易用的接口。
2>common层
位于三层的中间,依赖于base层提供的接口。common层提供可供复用的组件,它是典型的MVC模式中的M,
和页面内的具体功能没有直接关系。common层的功能是给page层提供组件。
3>page层
位于三层的顶端。这一层和页面里的具体功能需求直接相关,是MVC模式中的C。
page层依赖于base层和common层。page层的功能是完成页面内的功能需求。
拿YUI2和jQuery组件库举例子:
YUI2本身分成三大部分:Core、Utilities、Widget,其对应分层如下
Core –> base层
Utilities –> common层
Widget –> common层
jQuery本身分成两大部分:jQuery核心文件和jQuery UI文件,后者依赖于前者,其对应分层如下
jQuery核心 –> base层
jQuery UI –> common层
3.编程实用技巧
1>弹性
思考如何让自己的代码具备很高的扩展弹性,思考让自己的代码更具应对需求变化。
2>多用className进行功能相似点的程序挂钩而不是标签名
3>用hash对象来替代类似于test(3, null, null, 5)传递参数的方式,就不用过于遵循参数传递的顺序及个数问题
一律用hash映射方式进行传参,应用接收参数的时候可读性也增加了一些。整体而言更加灵活。
5.其他问题
1.prototype和内置类
1> 我们可以通过扩展prototype原型能够扩展内置类的方法,要记住扩展方法中的this代表的是实例化的对象。
2> 我们不但可以扩展内置类的方法,还可以重写内置类的方法。
3> 修改内置类的原型在多人合作时可能对别人的代码造成影响,存在冲突隐患
2.标签的自定义属性
1> 从兼容性考虑,对于常规属性,统一使用node.xxx的方式读取,对于自定义属性,统一使用node.getAttribute(‘xxx’)读取
2> 自定义属性的反序列化
4> 利用事件冒泡机制
冒泡的思路是在祖先节点上监听事件,有效减小内存开销
5> 改变DOM样式的三种方式
(1)直接设置style
(2)添加预先设定的类
(3)添加预先设定的css文件(通常用于全站皮肤设定的类似功能)