- DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构
Node
Node类型:
- Node.ELEMENT_NODE(1);
一个 元素 节点,例如<p>
和<div>
。 - Node.TEXT_NODE(3);
Element
或者Attr
中实际的 文字 - Node.CDATA_SECTION_NODE(4);
一个CDATASection
,例如<!CDATA[[ … ]]>
。 - Node.PROCESSING_INSTRUCTION_NODE(7);
一个用于XML
文档的ProcessingInstruction (en-US)
,例如<?xml-stylesheet ... ?>
声明。 - Node.COMMENT_NODE(8);
一个注释节点 - Node.DOCUMENT_NODE(9);
一个Document
节点。 - Node.DOCUMENT_TYPE_NODE(10);
描述文档类型的DocumentType
节点。例如<!DOCTYPE html>
就是用于 HTML5 的 - Node.DOCUMENT_FRAGMENT_NODE(11);
一个DocumentFragment
节点
Node的方法和属性:
- 节点类型:
if(someNode.nodeType == Node.ELEMENT_NODE){} // 在IE中无效 if(someNode.nodeType == 1){} // 适用于所有的浏览器
- 节点名称、节点值:
// 使用nodeName、nodeValue之前,最好先检查一下nodeType if(someNode.nodeType == 1){ value = someNode.nodeName; value = someNode.nodeValue; }
- 孩子节点:
// someNode.childNodes返回一个类型为NodeList的类数组对象 // DOM结构的变化能够自动反映在NodeList对象中 // 可以通过下标和item方法来访问 var first = someNode.childNodes[0]; var second = someNode.childNodes.item(1); // 具有length属性 var count = someNode.childNodes.length; // 使用slice方法将其转化成数组(在IE8之前版本中无效,IE8及更早版本将NodeList实现为一个COM对象[可以使用循环]) var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes, 0); // 通用方法 function convertToArray(nodes){ var array = null; try{ array = Array.prototype.slice.call(nodes, 0); } catch(ex) { array = new Array(); for(var i = 0, len = nodes.length; i < len; i++){ array.push(nodes[i]); } } }
- 父节点、前一个兄弟节点、后一个兄弟节点——
someNode.parentNode、someNode.previousSibling、someNode.nextSibling
- 第一个孩子、最后一个孩子——
someNode.firstChild、someNode.lastChild
- 是否有孩子节点
// someNode.hasChildNodes() // 在节点包含一或多个子节点的情况下返回true // 比查询childNodes列表的length属性更简单
- 访问文档根节点——
someNode.ownerDocument
- 在末尾添加节点
// appendChild() 返回新增的节点 var returnNode = someNode.appendChild(newNode); // 如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置
- 在特定位置添加节点
// 在someNode的子节点中的第一个节点之前插入新节点 var returnNode = someNode.insertBefore(newNode, someNode.firstChild);
- 替换节点
// 要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置 // 从技术上讲,被替换的节点仍然还在文档中,但它在文档中已经没有了自己的位置 var returnNode = soemNode.replaceChild(newNode, someNode.firstChild);
- 移除节点
// 通过removeChild()移除的节点仍然为文档所有,只不过在文档中已经没有了自己的位置 var formerFirstChild = someNode.removeChild(someNode.firstChild);
- 复制节点(深复制和浅复制)
/*
<ul>
<ul>item 1</ul>
<ul>item 1</ul>
<ul>item 1</ul>
</ul>
*/
// 深复制
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); // 3(IE < 9)或7
// 浅复制
var shallowList = myList.cloneNode(false);
alert(shallowListList.childNodes.length); // 0
// cloneNode()方法不会复制添加到DOM节点中的JavaScript属性,例如事件处理程序等
// IE在此存在一个bug,即它会复制事件处理程序,所以我们建议在复制之前最好先移除事件处理程序
Node类型详解:
Document类型
Document
类型表示文档HTMLDocument
继承自Document
类型document
对象是HTMLDocument
的一个实例
Document节点特征
❏ nodeType的值为9;
❏ nodeName的值为"#document";
❏ nodeValue的值为null;
❏ parentNode的值为null;
❏ ownerDocument的值为null;
❏ 其子节点可能是一个DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction或Comment
- 在
Firefox
、Safari
、Chrome
和Opera
中,可以通过脚本访问Document
类型的构造函数和原型。但在所有浏览器中都可以访问HTMLDocument
类型的构造函数和原型,包括IE8
及后续版本
Document的属性和方法
- 在Node类型中的属性和方法都可以用
- 获得HTML页面中的
<html>
元素——document.documentElement
- 获得HTML页面中的
<body>
元素——document.body
- 所有浏览器都支持
document.documentElement
和document.body
属性 - 获得HTML页面中
<!DOCTYPE html>
引用——document.doctype
(不同浏览器支持差别很大,具体看文档) - 浏览器在处理位于
<html>外部的注释
方面存在很多差异 - 我们都用不着在
document
对象上调用appendChild()
、removeChild()
和replaceChild()
方法,因为文档类型(如果存在的话)是只读的,而且它只能有一个元素子节点(该节点通常早就已经存在了) - 获得网页的标题
// 获取文档标题 var originalTitle = document.title; // 设置文档标题 document.title = "Anita-Mui";
- 获得地址栏中URL、页面的域名domain、链接到当前页面的那个页面的URL referrer
// 获得完整的URL(不可以设置) // http://www.wrox.com/WileyCDA/ var url = document.URL; // 获得域名 // www.wrox.com(可以设置) var domain = document.domain; // 设置——有限制 document.domain="wrox.com"; // 不能设置www.baidu.com之类 // document.domain设置为"wrox.com"之后,就不能再将其设置回"p2p.wrox.com",否则将会导致错误 // 取得来源页面的URL(不可以设置) var referrer = document.referrer;
- 查找元素(
getElementById()
和getElementsByTagName()
)// <div id = "myDiv">Some text</div> // 除IE7及更早版本之外的所有浏览器中都将返回null // IE8及较低版本不区分ID的大小写,因此"myDiv"和"mydiv"会被当作相同的元素ID // 如果页面中多个元素的ID值相同,getElementById()只返回文档中第一次出现的元素 // 不能让表单字段的name特性与其他元素的ID相同 var div = document.getElementById("myDiv"); // 返回的是包含零或多个元素的NodeList // 在HTML文档中,这个方法会返回一个HTMLCollection对象,作为一个“动态”集合,该对象与NodeList非常类似 var images = document.getElementsByTagName("img"); alert(images[0].src); // HTMLCollection对象还有一个方法,叫做namedItem() // <img src="myimage.gif" name="myImage"> var myImage = images.namedItem("myImage"); // HTMLCollection还支持按名称访问项 var myImage=images["myImage"]; // 获得文档中所有元素 // 由于IE将注释(Comment)实现为元素(Element),因此在IE中调用getElementsByTagName("*")将会返回所有注释节点 var allElements = document.getElementsByTagName("*"); // 在HTML中名称不需要区分大小写,在XML中,需要区分大小写
- 获取单选按钮(
getElementsByName()
)// 所有单选按钮必须具有相同的name特性 var radios = document.getElementsByName("color");
- 特殊集合
❏ document.anchors,包含文档中所有带name特性的<a>元素; ❏ document.forms,包含文档中所有的<form>元素,与document.getElementsByTagName("form")得到的结果相同; ❏ document.images,包含文档中所有的<img>元素,与document.getElementsByTagName ("img")得到的结果相同; ❏ document.links,包含文档中所有带href特性的<a>元素。
- DOM一致性检测
// 这个方法接受两个参数:要检测的DOM功能的名称及版本号 // 如果浏览器支持给定名称和版本的功能,则该方法返回true // 除了检测hasFeature()之外,还同时使用能力检测 var hasXmlDom = document.implementation.hasFeature("XML", "1.0");
- 文档写入
<!-- write()会原样写入,而writeln()则会在字符串的末尾添加一个换行符(\n)。在页面被加载的过程中,可以使用这两个方法向页面中动态地加入内容 --> <!DOCTYPE html> <html lang="en"> <head> <title>Document</title> </head> <body> <p> The current date and time is: <script type="text/javascript"> // 使用document.write()在页面被呈现的过程中直接向其中输出了内容 document.write("<strong>" + (new Date()).toString() + "</strong>"); </script> </p> <!-- 可以包含动态资源 --> <script type="text/javascript"> document.write("<script type=\"text/javascript\" src=\"file.js\" + "<\/script>"); </script> // 如果在文档加载结束后再调用document.write(),那么输出的内容将会重写整个页面 <script type="text/javascript"> window.onload = function(){ document.write("Hello World"); }; </script> // 方法open()和close()分别用于打开和关闭网页的输出流。如果是在页面加载期间使用write()或writeln()方法,则不需要用到这两个方法。 </body> </html>