JavaScript 通过 Document 类型表示文档。
document
对象是 HTMLDocument(继承自 Document 类型)的一个实例,表示整个 HTML 页面。而且document
对象是window
对象的一个属性,因此可以将其作为全局对象来访问。
1. 特征
nodeType:9
nodeName:#document
nodeValue:null
parentNode:null
ownerDocument:null
2. 文档的子节点
DOM 标准中规定,Document 节点的子节点可以是 DocumentType、Element、ProcessingInstruction 或 Comment,但是还有两个内置的快捷访问其子节点的方式。
(1)documentElement
该属性始终指向 HTML 页面中的 html
元素
var html = document.documentElement;
(2)通过子节点访问文档元素
//=> 不兼容
var html = document.firstChild;
var html = document.childNodes[0];
作为 HTMLDocument 的实例,document
对象还有一个 body
属性,直接指向 body
元素。
var body = document.body;
Document 类型的另一个可能的子节点是 DocumentType。 通常将 <!DOCTYPE>
标签当作一个与文档其他实体不同的实体,可以通过 doctype
属性来访问其信息。
var doctype = document.doctype;
浏览器对 document.doctype
的支持差别很大:
IE8 及以前版本,会错误将其解释为一个注释节点,
document.doctype
值始终为null
IE9+ 及 FireFox,会将其作为文档的第一个子节点
Safari、Chrome 及 Opera,不作为文档的子节点,不会出现在
document.childNodes
中
从技术上讲,出现在 html
元素外部的注释应该算是文档的子节点。但是不同的浏览器存在很大差异。
<!-- 第一条注释 -->
<html>
</html>
<!-- 第二条注释 -->
IE8 及之前版本、Safari 3.1 及其更高版本、Opera、Chrome 只为第一条注释创建节点,不为第二条注释创建节点。结果,第一天注释成为文档中的第一个子节点
IE9+ 会将两条注释都创建节点
Firefox、Safari 3.1 及其以前版本,会忽略这两条注释
3. 文档信息
作为 HTMLDocument 的实例,document
对象还有一些标准的 Document 类型没有的属性,提供了 document 对象所表现的网页的一些信息
title
属性,包含着 title
元素中的文本。通过这个属性可以取得页面中的标题,也可以修改当前页面的标题并反映到浏览器的标题栏中。注意的是,修改 title
属性的值不会改变 title
元素
var orginalTitle = document.title;
document.title = 'new page title';
URL
属性包含页面中完整的 URL 地址
var url = document.URL;
domain
属性值包含页面的域名
var domain = document.domain;
referrer
属性保存着链接到当前页面的那个页面的 URL,在没有来源页面的情况下,referrer
属性可能会包含空字符串
var referrer = document.referrer;
这三个关于网页请求的只有 domain
是可以设置的,但是由于安全方面的限制,也并非可以给 domain
设置任何值。如果 URL 中包含一个子域名,如:p2p.wrox.com
,那么只能将 domain 设置为 wrox.com
。不能将这个属性设置为 URL 中不包含的域。
//=> 假设页面来自于 p2p.wrox.com
document.domain = 'wrox.com'; //=> 成功
document.domain = 'nczonline.net'; //=> 出错
由于跨域安全的限制,来自不同子域的页面无法通过 JavaScript 通信。而通过将每个页面的 document.domain
设置为相同的值,这些页面就可以互相访问对方包含的 JavaScript 对象了。
浏览器对 domain
属性还有一个限制,如果域名一开始是松散的(loose),那么不能将它再设置为紧绷的(tight)。即
//=> 假设页面来自于 p2p.wrox.com
document.domain = 'wrox.com'; //=> 松散的,成功
document.domain = 'p2p.wrox.com'; //=> 紧绷的,出错
4. 查找元素
取得元素的操作可以使用 document
对象的几个方法来完成。
其中,有:getElementById
、getElementsByTagName
、getElementsByName
、getElementsByClassName
这几个方法
对于 getElementById
,必须与页面元素的 id 特性严格匹配,包括大小写。如果页面中有多个元素的 ID 相同,只返回文档中第一次出现的元素。
其中 IE7及低版本还有个有意思的怪癖:name 属性与给定 ID 匹配的表单元素也会被该方法返回。
对于 getElementsByTagName
、getElementsByName
、getElementsByClassName
这三个方法,都会返回一个 HTMLCollection 对象。
HTMLCollection 对象是一个动态集合,与 NodeList 对象类似,可以通过方括号或 item()
访问其中的项。
HTMLCollection 对象还有一个 namedItem
方法,使用这个方法可以通过元素的 name
属性来取得集合中的特定项。
// 对于 <img name="myImage"></img>
var myImage = image.namedItem('myImage');
同样支持直接按 name
属性来访问,这就为我们取得实际想要的元素提供便利。
var myImage = image['myImage'];
对 HTMLCollection 而言,我们向方括号中传入数值或字符串的索引值,在后台,对数值索引就会调用
item()
方法,而对字符串索引就会调用namedItem()
方法
5. 特殊的集合
这些集合都是 HTMLCollection 对象,为访问文档常用的部分提供快捷方式,包括:
document.anchors:包含文档中所有带 name 属性的 a 标签
document.applets:已不再使用
document.images:包含文档中的所有 img 标签
document.forms:包含文档中所有的 form 标签
document.links:包含文档中所有带 href 属性的 a 标签
6. DOM 一致性的检测
可以通过 document.implementtetion.hasFeature()
检测 DOM 功能的名称和版本号。
但是,检测并不一定准确,因为实现者可以自行决定是否与 DOM 规范的不同部分保持一致。返回 true
不意味着实现与规范一样。
所以最好还是进行能力检测。
7. 文档写入
document
对象有将输出流写入到网页中的能力。这个能力体现在四个方法中:write()
、writeln()
、open()
、close()
。一般不需要使用。
其中 write()
和 writeln()
方法都接受一个字符串参数,即要写入输出流中的文本,write 会原样写入,而 writeln 会在字符串末尾添加一个换行符。在页面被加载的过程中,可以使用这两个方法向页面中动态加入内容。这两个方法都会重写整个页面
方法 open()
和 close()
分别用于打开和关闭网页的输出流,如果在页面加载期间使用前两个方法,则不需要用到这连个方法。