读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅。
内容也有自己的一些补充。
JavaScript由Netscape公司与Sun公司合作开发,在JavaScript之前,web浏览器只是显示文本文档的软件,JavaScript之后,网页内容不再局限于枯燥的文本,交互性显著改善。在JavaScript的第一个版本,即JavaScript 1.0版本,出现在1995年推出的Netscape Navigator 2浏览器中。
在JavaScript 1.0发布时,浏览器市场主要是Netscape Navigator,后来IE开始追赶,微软在IE3时发布了自己的VBScript语言,同时以JScript为名发布了JavaScript的第一个版本,并很快追上了Netscape的步伐。面对微软的竞争,Netscape与Sun公司联合ECMA(欧洲计算机制造商协会)对JavaScript语言进行了标准化,于是出现了ECMAScript语言,这是同一种语言的另一个名字。
到了1996年,JavaScript、ECMAScript、JScript--随便怎么称呼,已经站稳了脚本,Netscape与微软的第三版浏览器都不同程度的支持JavaScript 1.1语言。
在JavaScript早期版本向程序员提供了查询和操控Web文档某些内容的手段,比如:
- document.images[2]
- dodument.forms['details']
现在人们通常把这种试验性质的初级DOM称为“第0级DOM”(DOM level 0),在还未形成统一标准的初级阶段,“第0级DOM”的常见用途是翻转图片和验证表单数据。
在1997年6月,Netscape Navigator 4发布,10月,IE4发布。这两个早起版本都对他们的浏览器进行了改进,大幅扩展了DOM,同时也接触到一个新名词:DHTML。
不幸的是,NN4和IE4浏览器使用了两种不兼容的DOM。程序员要写两套代码。
NN4中DOM元素为层,层有唯一的ID:
document.layers['myElement']
而微软的DOM需要这样引用:
document.all['myElement']
就在DOM产生分歧,浏览器厂商大战时,W3C推出了一个标准化的DOM,令人欣慰的事,Netscape与微软以及其他浏览器制造商都接受了新的标准,并于1998年10月完成了“第1级DOM”(DOM Level 1)。
DOM:Document Object Model 文档对象模型
JavaScript中的对象分为三种:
1、用户定义对象:由程序员创建的对象
2、內建对象:内建在JavaScript语言中的对象,如Array、Math和Date等
3、宿主对象:由宿主环境(浏览器)提供的对象,如window、document
window对象对应着浏览器窗口本身,这个对象的属性和方法通常称为BOM(浏览器文档模型)。
先看三种:元素节点、文本节点、属性节点
<p class="info">my name is Gavin</p>
标签的名字就是元素的名字,这里面有一个元素节点p,一个文本节点“my name is Gavin”,以及一个属性节点class="info"。
属性节点总是被包含在元素节点中,并不是所有的元素节点都有属性节点,在所有的属性都被元素包含。
其中getElementById()返回一个对象,getElementsByTagName()与getElementsByClassName()返回一个对象数组。
每个节点都是一个对象。
setAttribute方法是“第一级DOM”(DOM level 1)的组成部分,可以设置任意元素的节点的任意属性。在“第一级DOM”出现之前,还可以用另外一个方法设置大部分元素的属性,这个方法到现在仍然有效。
- img.src = 'xxx'
- // 等价
- img.setAttribute( 'src', 'xxx' );
使用“第一级DOM”的优势是:
node.childNodes 获取任何一个元素的所有子元素
nodeTyoe总共有12种可取值,但其中仅有3个具有实用价值。
如果要改变一个文本节点的值,那就实用DOM提供的nodeValue属性,它用来得到(和设置)一个节点的值。
element.nodeValue
注意,文本节点可能是其他节点的子节点,在获取时尤其注意:
- <p>my name is Gavin.</p>
- <script>
- var oP = document.getElementsByTagName('p');
- oP[0].nodeValue; // null
- op[0].childNodes[0].nodeValue; // my name is Gavin.
- </script>
- node.childNodes[0] === node.firstChild
- node.childNodes[ node.childNodes.length - 1 ] === node.lastChild
补充:nextSibling、previousSibling:兄弟节点
javascript:
伪协议对象检测
if ( !xxx ) return false;
浏览器嗅探
"真"协议用来在因特网上的计算机之间传输数据包,如HTTP协议(http://)、FTP协议(ftp://)等,伪协议是一个非标准化的协议,javascript:
伪协议可以让我们通过一个链接来调用JavaScript函数。
通过伪协议来调用JavaScript函数的做法非常不好,不是最佳实践。
对于视力残疾的用户往往看不清屏幕上的鼠标指针,他们往往更喜欢使用键盘。众所周知,不使用鼠标也可以浏览web。键盘上的tab
键可以让我们从这个链接移动到另一个链接,然后按下回车键启用当前链接。
在键盘事件中有一个onkeypress
事件,按下键盘的任何一个键都会触发onkeypress事件,但这个键很容易出现问题,因为即使按下tab键也会触发该事件!
onclick
事件更聪明,用tab键移到链接上,按下回车键,链接也能访问。
这些都是DOM Core的组成部分,他们并不专属于JavaScript,任何支持DOM的程序设计语言都可以使用它们。
而对于
这些属性属于HTML DOM,在DOM Core出现很久之前就已经为人们所熟悉了。
大多数情况下,同样的操作即可以使用DOM Core实现也可以用HTML DOM实现。HTML DOM通过更加简短,只能用来处理HTML文档。
element.innerHTML 方法可以读写元素的内容。几乎所有的浏览器都支持innerHTML,但这个属性不是W3C DOM的标准属性,现在已经在HTML5规范中,始于IE4浏览器。
和document.write()类似,innerHTML也是HTML专有属性,不能用于其他标记语言文档,在MIME类型为application/xhtml+xml的XHMLT文档中,该属性会被忽略。
通过createElement与createTextNode只是创建文档碎片,只有执行appendChild才会插入到文档中。
appendChild除了可以把文档碎片插入到文档树中,还可以连接文档碎片。
比如:
MIME类型application/xhtml+xml与document.write()不兼容,浏览器呈现这种XHTML文档时不会执行document.write()方法。
另外,document.write()最大的问题是不能进行结构与行为分离。
备注:关于document.write()主要有两种使用方式:
第一种:当页面加载完成后,浏览器输出流自动关闭,此时进行document.write()方法将打开一个新的输出流,它将清除当前页面内容。
第二种:调用document.write()方法在窗口中打开窗口,框架中产生新文档,这种方式必须用document.close()关闭,并且继续使用document.write()写入的内容不会清除文档,而是继续追加。
element.innerHTML 方法可以读写元素的内容。几乎所有的浏览器都支持innerHTML,但这个属性不是W3C DOM的标准属性,现在已经在HTML5规范中,始于IE4浏览器。
和document.write()类似,innerHTML也是HTML专有属性,不能用于其他标记语言文档,在MIME类型为application/xhtml+xml的XHMLT文档中,该属性会被忽略。
appendChild除了可以把文档碎片插入到文档树中,还可以连接文档碎片。
比如:
通过createElement与createTextNode只是创建文档碎片,只有执行appendChild才会插入到文档中。
- var p = document.createElement('p');
- var text = document.createTextNode('my name is Gavin.');
- p.appendChild( text );
- document.body.appendChild( p );
insertBefore -- 在现有元素前插入元素
parentElement.insertBefore( newElement, targetElement );
没有insertAfter方法,可以结合insertBefore来实现
- function insertAfter ( newElement, targetElement ) {
- var parent = targetElement.parentNode;
- if ( parent.lastChild == targetElement ) {
- parent.appendChild( newElement );
- } else {
- parent.insertBefore( newElement, targetElement.nextSiblings );
- }
- }
ajax的技术核心是XMLHttpRequest。在微软较早的IE5中以ActiveX对象的形式实现了一个名叫XMLHTTP的对象,在较早IE中,创建对象的方式为:
var request = new ActiveXObject("Msxml2.XMLHTTP.3.0");
在其他浏览器上的创建方式为:
var request = new XMLHttpRequest();
更烦的是,不同IE版本中使用的XMLHTTP对象不完全相同,为了兼容所有浏览器,需要这样写:
- function getHttpObject() {
- if ( typeof XMLHttpRequest == 'undefined ) {
- XMLHttpRequest = function () {
- try {
- return new ActiveXObject("Msxml2.XMLHTTP.6.0");
- } cache ( e ) {}
- try {
- return new ActiveXObject("Msxml2.XMLHTTP.3.0");
- } cache ( e ) {}
- try {
- return new ActiveXObject("Msxml2.XMLHTTP");
- } cache ( e ) {}
- }
- }
- return new XMLHttpRequest();
- }
XMLHttpRequest对象由许多方法
- request.open( 'GET', 'xxx.json', true );
- request.onreadystatechange = function () {}
- request.send();
onreadystatechange事件XMLHttpRequest返回响应时触发。
返回响应时,浏览器会在不同阶段更新readyState的值,它有5个可能值:
备注:关于HTML、XHTML、HTML5的区别,可以看这篇文档:
在HTML早起,W3C成立之前,基本没有标准,标准都在在实现中定义的。一直从HTML2.0到4.0、4.01,这种情况下,HTML标准不是很规范,浏览器也对HTML页面的错误相当宽容。导致HTML作者也出了很多错误的HTML页面。
后来W3C意识到这个问题,开始制定标准,为了规范HTML,W3C结合XML制定了XHTML1.0标准,按照XML的要求规范HTML,并定义了一个新MIME Type:application/xhtml+xml,W3C的初衷是对这个MIME TYPE的浏览器实行强制错误检查,如果页面有错误,就要显示错误。很多开发者拒绝使用这个MIME TYPE,W3C不得已,在XHTML1.0后附加了一个附录C。允许开发者使用XHTML来写页面,同时使用原来的MIME TYPE:application/html。这个MIME TYPE不会触发浏览器的强制错误检查。
如果readyState属性值变成了4,则说明服务器已经发回了数据。
访问服务器发送回来的数据需要通过两个属性,一个是responseText,这个用于保存文本字符串形式的数据,另一个是responseXML属性,用于保存Content-Type头部中指定为“text/xml”的数据,这其实是一个DocumentFragment对象。你可以使用各种方法来操作这个DOM对象,这也是XMLHttpRequest中有XML的原因。
渐进增强
则必然支持平稳退化
。
8.3.1 选用HTML、XHTML还是HTML5
不管使用哪一种标记,必须要与DOCTYPE声明保持一致。
XHMLT比HTML的规则更严格。比如在写属性时,HTML允许使用大写字母,也可以使用小写字母,XHTML却要求所有的标签名和属性名都必须使用小写字母。
有了XHTML的教训,WHATWG和W3C在制定下一代HTML标准,也就是HTML5的时候,就将向后兼容作为一个很重要的原则。HTML5加入了很多特性,但最重要的特性是,不会break已有的网页。你可以将网页的第一行改为,他就成了一个HTML5页面,可以照常在浏览器中显示。
总共才15个字符,这个声明同时也支持HTML与XHTML标记。
某些浏览器要根据DOCTYPE来决定使用标准模式,还是兼容模式来呈现页面,兼容模式意味着浏览器要模仿早起浏览器的“怪异行为”,并允许不规范的页面也能正常工作。一般来说,我们都应该坚持使用标准模式,避免触发兼容模式,HTML5的DOCTYPE默认就是标准模式。
此外还有XHTML5,即用XML的规则来编写HTML5。
文档中的每个元素都是一个对象,每个对象都有各种各样的属性,比如:parentNode、childNodes、firstChild、lastChild、nextSibling、previousSibling等,表示节点的关心信息。
还有一些属性:nodeName、nodeValue、nodeType,表示节点的类型信息。
除此之外,还有一个style属性,表示节点的样式信息。
element.style.color
对于font-family
,在获取的时候会出错,原因为:JavaScript中连字符-
为减法运算,所以会理解为获取font属性,然后对family做减法运算,而family此时为变量,但我们并没有声明这个变量,继而引发错误。
- // 错误写法!!
- element.style.font-family;
当引用一个中间带减号的CSS属性时,DOM要求使用驼峰命名法:
- // 正确写法
- element.style.fontFamily;
不管有多有连字符,一律采用驼峰写法:比如magrin-top-width,写为:marginTopWidth。
style属性只能返回内联样式。
element.style.property = value;
:first-child,:last-child选择器是CSS2中的
:nth-child()和:nth-of-type()是CSS3中的
在使用CSS时,不要人云亦云的认为表格都是不好的,虽然用表格布局不是好主意,但利用表格来显示数据却是理所当然的。
- // 读
- element.className
- // 写
- element.className = value
className在设置的时候是替换(而不是追加)。可以利用字符串拼接,达到追加的效果
element.clssName += ' info';
HTML5是HTML语言当前及未来的新标准,HTML规范从HTML4到XHTML,再到Web Apps1.0,最后又回到HTML5,整个过程充满了艰辛与争议。
在结构层,HTML5添加了很多新的标记元素,如、
、
和等。
HTML5还提供了更多的交互即媒体元素,如、
、
。
表单也进行了增强,新增了颜色选择器
、数据选择器
、滑动条
和进度条
等。
还有很多新的JavaScript API,比如:Geolocation
、Storage
、Drag-and-Drop
、Socket
以及多线程
等。
另外,通过新的MIME TYPE,HTML5保持了向后兼容,就算写代码很不规范,也没问题。
所谓库,就是可重用的代码包,具有如下的一些优点:
库也存在问题:
在选择时,建议考虑如下问题:
一定要尽可能想办法减少网页文档的大小,并让浏览器缓存文件。除此之外,当然还要让用户尽可能的加载到页面。
内容分发网络(CDN,Content Delevery Network)可以解决分布共享库的问题。CDN是一个由服务器构成的网络,这个网络的用户就是分散存储一些公共的内容。CND的每台服务器都包含库的一份副本,这些服务器分布在世界上不同的国家和地区,以便达到和利用带宽和加快下载的目的。
浏览器访问库的时候使用一个公共的URL,而CDN的地层则通过地理位置最近、速度最快的服务器提供相应的文件,从而解决了整个系统中的瓶颈问题。
这些文件是共享的,当用户从一个站点跳到另一个站点,他们就不用再重复的下载相同的文件了。