Document 类型
JavaScript 通过 Document 类型表示文档。在浏览器中, document 对象是 HTMLDocument (继承自 Document 类型)的一个实例,表示整个 HTML 页面。而且, document 对象是 window 对象的一个属性,因此可以将其作为全局对象来访问。
Document 类型可以表示 HTML 页面或者其他基于 XML 的文档。不过,最常见的应用还是作为HTMLDocument 实例的 document 对象。通过这个文档对象,不仅可以取得与页面有关的信息,而且还能操作页面的外观及其底层结构。
在 Firefox、Safari、Chrome 和 Opera 中,可以通过脚本访问 Document 类型的构造函数和原型。 但在所有浏览器中都可以访问 HTMLDocument 类型的构造函数和原型,包括 IE8及后续版本。
虽然 DOM 标准规定 Document 节点的子节点可以是 DocumentType 、 Element 、 ProcessingIn-
struction 或 Comment , 但还有两个内置的访问其子节点的快捷方式。 第一个就是 documentElement属性, 该属性始终指向 HTML 页面中的 <html> 元素。 另一个就是通过 childNodes 列表访问文档元素,但通过 documentElement 属性则能更快捷、更直接地访问该元素。
如下所示:
<html>
<body>
</body>
</html
页面在经过浏览器解析后,其文档中只包含一个子节点,即 <html> 元素。可以通过documentElement 或 childNodes 列表来访问这个元素,即:
var html = document.documentElement; //取得对<html>的引用
alert(html === document.childNodes[0]); //true
alert(html === document.firstChild); //true
例子说明, documentElement 、 firstChild 和 childNodes[0] 的值相同,都指向 <html>元素。
作为 HTMLDocument 的实例, document 对象还有一个 body 属性,直接指向 <body> 元素。
var body = document.body; //取得对<body>的引用
所有浏览器都支持 document.documentElement 和 document.body 属性。
Document 另一个可能的子节点是 DocumentType,但是由于浏览器对 document.doctype 的支持不一致,因此这个属性的用处很有限。
文档信息
作为 HTMLDocument 的一个实例, document 对象还有一些标准的 Document 对象所没有的属性,这些属性提供了 document 对象所表现的网页的一些信息。比如属性 title ,包含着<title> 元素中的文本——显示在浏览器窗口的标题栏或标签页上。 通过这个属性可以取得当前页面的标题, 也可以修改当前页面的标题并反映在浏览器的标题栏中。
介绍3个与网页请求有关的属性,它们是 URL 、domain 和 referrer 。 URL 属性中包含页面完整的 URL(即地址栏中显示的 URL) , domain 属性中只包含页面的域名,而 referrer属性中则保存着链接到当前页面的那个页面的 URL。在没有来源页面的情况下, referrer 属性中可能会包含空字符串。所有这些信息都存在于请求的 HTTP 头部,只不过是通过这些属性让我们能够在JavaScrip 中访问它们而已,
如下所示:
//取得完整的 URL
var url = document.URL;
//取得域名
var domain = document.domain;
//取得来源页面的 URL
var referrer = document.referrer;
URL 与 domain 属性是相互关联的。如果 document.URL 等于http://www.wrox.com/WileyCDA/,
那么 document.domain 就等于 www.wrox.com。
在这 3 个属性中,只有 domain 是可以设置的。但由于安全方面的限制,不能将这个属性设置为 URL 中不包含的域。
//假设页面来自 p2p.wrox.com 域
document.domain = "wrox.com"; // 成功
document.domain = "nczonline.net"; // 出错!
当页面中包含来自其他子域的框架或内嵌框架时,能够设置 document.domain 就非常方便了。由于 跨 域 安 全 限 制 , 来 自 不 同 子 域 的 页 面 无 法 通 过 JavaScript 通 信 。 而 通 过 将 每 个 页 面 的document.domain 设置为相同的值,这些页面就可以互相访问对方包含的 JavaScript 对象了。
假设有一个页面加载自 www.wrox.com,其中包含一个内嵌框架,框架内的页面加载自 p2p.wrox.com。
由于 document.domain 字符串不一样,内外两个页面之间无法相互访问对方的 JavaScript 对象。但如
果将这两个页面的 document.domain 值都设置为 "wrox.com" ,它们之间就可以通信了。
浏览器对 domain 属性还有一个限制,即如果域名一开始是“松散的” (loose) ,那么不能将它再设
置为“紧绷的” (tight) 。换句话说,在将 document.domain 设置为 "wrox.com" 之后,就不能再将其设置回 "p2p.wrox.com" ,否则将会导致错误。
查找元素
Document 类型为此提供了两个方法: getElementById() 和 getElementsByTagName()。
getElementById() 如果找到相应的元素则返回该元素,如果不存在带有相应 ID 的元素,则返回 null,如果页面中多个元素的 ID 值相同,只返回文档中第一次出现的元素。
getElementsByTagName() 在 HTML 文档中,这个方法会返回一个 HTMLCollection 对象,作为一个“动态”集合,该对象与 NodeList 非常类似。
与 NodeList 对象类似,可以使用方括号语法或 item() 方法来访问 HTMLCollection 对象中的项。 而这个对象中元素的数量则可以通过其 length 属性取得。
如下所示:
var images = document.getElementsByTagName("img");
alert(images.length); //输出图像的数量
alert(images[0].src); //输出第一个图像元素的 src 特性
alert(images.item(0).src); //输出第一个图像元素的 src 特性
假设上面的页面中包含如下 <img> 元素:<img src="myimage.gif" name="myImage">,则可以
var myImage = images.namedItem("myImage");
var myImage = images["myImage"];
要想取得文档中的所有元素,可以向 getElementsByTagName() 中传入 "*" 。在 JavaScript 及 CSS
中,星号( * )通常表示“全部” 。
如 var allElements = document.getElementsByTagName("*");返回整个页面中的所有节点元素。
getElementsByName()只有 HTMLDocument 才有的方法, 这个方法会返回带有给定 name 特性的所有元素。
特殊集合
除了属性和方法, document 对象还有一些特殊的集合。这些集合都是 HTMLCollection 对象,为访问文档常用的部分提供了快捷方式:
document.anchors ,包含文档中所有带 name 特性的 <a> 元素;
document.applets ,包含文档中所有的 <applet> 元素,因为不再推荐使用 <applet> 元素,所以这个集合已经不建议使用了;
document.forms , 包含文档中所有的 <form> 元素, document.getElementsByTagName("form")
得到的结果相同;
q document.images ,包含文档中所有的 <img> 元素,与 document.getElementsByTagName
("img") 得到的结果相同;
q document.links ,包含文档中所有带 href 特性的 <a> 元素。
DOM 一致性检测
由于 DOM 分为多个级别,也包含多个部分,因此检测浏览器实现了 DOM 的哪些部分就十分必要
了。 document.implementation 属性就是为此提供相应信息和功能的对象,与浏览器对 DOM 的实现直接对应。DOM1 级只为 document.implementation 规定了一个方法,即 hasFeature() 。这个方法接受两个参数:要检测的 DOM 功能的名称及版本号。如果浏览器支持给定名称和版本的功能,则该方法返回 true 。如下所示:
var hasXmlDom = document.implementation.hasFeature("XML", "1.0");
下表列出了可以检测的不同的值及版本号:
尽管使用 hasFeature() 确实方便,但也有缺点。因为实现者可以自行决定是否与 DOM 规范的不
同部分保持一致。即返回 true有时候也不意味着实现与规范一致
文档写入
将输出流写入到网页中的能力,体现在下列 4 个方法中: write() 、 writeln() 、 open() 和 close() 。
其中, write() 和 writeln()方法都接受一个字符串参数,即要写入到输出流中的文本。 write() 会原样写入,而 writeln() 则会在字符串的末尾添加一个换行符( \n ) 。在页面被加载的过程中,可以使用这两个方法向页面中动态地加入内容。
如下所示:
<html>
<head>
<title>document.write() Example</title>
</head>
<body>
<p>The current date and time is:
<script type="text/javascript">
document.write("<strong>" + (new Date()).toString() + "</strong>");
</script>
</p>
</body>
</html>
此外,还可以使用 write() 和 writeln() 方法动态地包含外部资源,例如 JavaScript 文件等。如:
<html>
<head>
<title>document.write() Example 3</title>
</head>
<body>
<script type="text/javascript">
document.write("<script type=\"text/javascript\" src=\"file.js\">" +"<\/script>");
</script>
</body>
</html>
字符串 "<\/script>" 不会被当作外部 <script> 标签的关闭标签,因而页面中也就不会出现多余的内容了。
方法 open() 和 close() 分别用于打开和关闭网页的输出流。 如果是在页面加载期间使用 write()或 writeln() 方法,则不需要用到这两个方法。