DOM
DOM可以将任何HTML或者XML文档描述成一个由多层节点构成的结构。
一、节点层次
一)Node类型
DOM1定义了一个Node接口,该接口将由DOM中所有节点类型实现。
每一个节点都有一个nodeType属性,用于表明节点类型。节点类型由在Node类型中定义的12个数值常量来表示。
Node.ELEMENT_NODE(1);
Node.ATTRIBUTE_NODE(2);
Node.TEXT_NODE(3);
Node.CDATA_SECTION_NODE(4);
Node.ENTITY_REFERENCE_NODE(5);
Node.ENTITY_NODE(6);
Node.PROCESSING_INSTRUCTION_NODE(7);
Node.COMMENT_NODE(8);
Node.DOCUMENT_NODE(9);
Node.DOCUMENT_TYPE_NODE(10);
Node.DOCUMENT_FRAGMENT_NODE(11);
Node.NOTATION_NODE(12)。
<body> <input id="king" value="for the king!"/> </body> <script> window.onload = function () { var h = document.getElementById("king"); //方法一,在IE浏览器中不管用 if (h.nodeType == Node.ELEMENT_NODE) { console.log("This is a element."); } //方法二,适用于所有浏览器 if (h.nodeType == 1) { console.log("It's a element"); console.log("The node name is "+h.nodeName); //"INPUT"即为元素的标签名 console.log("The node value is "+h.nodeValue); //对于元素节点始终是null } } </script>
1.节点关系
每一个节点都有一个childNodes属性,其中保存着一个NodeList类数组对象(注意该对象是动态的随着DOM变化而变化),
<body> <div id="father"> <p>This is a p</p> <h5>A HTML5?</h5><br> <input value="just a input"> </div> </body> <script> var d = document.getElementById("father"); if (d.nodeType == 1) { console.log("The length of the children is "+ d.childNodes.length); //8 console.log("The first children is "+ d.childNodes[0].nodeName); //"#text" console.log("The second children node is "+ d.childNodes[1].nodeName); //"p" } </script>
parentNode属性:指向父节点
previousSilbling属性;前一个同胞节点
nextSilbling属性:后一个同胞节点
ownerDocument属性:指向表示整个文档的文档节点。
2.操作节点
1.appendChild():向childNodes列表末尾添加一个节点,返回添加的节点,如果该节点在文档中存在,移动之。
2.insertBefore(newNode,oldNode):把节点放在childNodes列表指定位置,如果参照节点为null,则添加到末尾。
3.replaceChild(new,old):替换childNodes列表中的节点。
4.removeChild():
5.cloneNode(boolean):true为深复制,连同子节点一起复制,false为浅复制只复制该节点。注意该方法不会复制
添加到DOM节点中的JS属性,如事件处理程序等。
<body> <h2 id="bother">Apple Orange</h2> <div id="father"> <p>This is a p</p> <h5>A HTML5?</h5><br> <input value="just a input"> </div> </body> <script> var h = document.getElementById("bother"); var d = document.getElementById("father"); var h2 = h.cloneNode(true); d.appendChild(h2); console.log(d.lastChild.nodeName); //H2 </script>
二)Document类型
在浏览器中,document对象是HTMLDocument对象(继承自Document对象)的一个实例,表示整个HTML页面,并且document对象是window对象的一个属性。
1.文档的子节点
1)document.documentElement:该属性指向<html>元素
2)document.body:指向<body>元素
3)document.doctype:浏览器差别很大,不常用。
2.文档信息
1)document.title:指向<title>元素的文本,可修改
2)document.URL:完整的URL信息
3)document.domain:只包含页面的域名,可设置
4)document.reference:包含来源页面的URL
当页面中包含来自其他子域的框架或内嵌框架时,能够设置 document.domain 就非常方便了。由
于 跨 域 安 全 限 制 , 来 自 不 同 子 域 的 页 面 无 法 通 过 JavaScript 通 信 。 而 通 过 将 每 个 页 面 的
document.domain 设置为相同的值,这些页面就可以互相访问对方包含的 JavaScript 对象了
浏览器对 domain 属性还有一个限制,即如果域名一开始是“松散的”(loose),那么不能将它再设
置为“紧绷的”(tight)。换句话说,在将 document.domain 设置为"wrox.com"之后,就不能再将其
设置回"p2p.wrox.com",否则将会导致错误
3.查找元素
1)document.getElementById(id):如果多个id相同,只返回第一个
2)document.getElementsByTagName(name):为了兼容,标签名不区分大小写,在HTML文档中返回一个HTMLCollection对象,
该对象有一个nameItem(name)方法,使用这个方法可以通过元素的name属性获得元素。注意,元素也有该方法,即element.getElementsByTagName()
3)document.getElementsByName(name):HTMLDocument才有的方法。
4.文档的写入
1)document.write(str):页面被加载的过程中动态地写入内容
2)document.writeln(str):与1)不同的是末尾加上了换行符
使用上面两个方法可以动态地包含文件资源。
如果在文档加载完成后调用上述两个方法,页面将会被重写:
<body> <p>Things you never see!</p> <script> //由于用了window.onload延迟执行函数,<p>元素中的文本会被重写。 window.onload = function () { document.write("<h2>Now the time is " + new Date().toLocaleDateString()+ "</h2>"); } </script> </body>
三)Element类型
Element用以表现HTML或XML中的元素。
要访问标签名,可以使用nodeName或者tagName。
var div = document.getElementById("myDiv"); alert(div.tagName); //"DIV" alert(div.tagName == div.nodeName); //true
if (element.tagName.toLowerCase() == "div"){ //这样最好(适用于任何文档) //在此执行某些操作 }
1.HTML元素
所有的HTML元素都由HTMLElement类型及其子类表示,该类型继承自Element类型,并添加了如下属性:
id,元素在文档中的唯一标识符。
title,有关元素的附加说明信息,一般通过工具提示条显示出来。
lang,元素内容的语言代码,很少使用。
dir,语言的方向,值为"ltr"(left-to-right,从左至右)或"rtl"(right-to-left,从右至左),
也很少使用。
className,与元素的 class 特性对应,即为元素指定的 CSS 类。没有将这个属性命名为 class,
是因为 class 是 ECMAScript 的保留字
var div = document.getElementById("myDiv"); alert(div.id); //"myDiv"" alert(div.className); //"bd" alert(div.title); //"Body text" alert(div.lang); //"en" alert(div.dir); //"ltr"
div.id = "someOtherId"; div.className = "ft"; div.title = "Some other text"; div.lang = "fr"; div.dir ="rtl";
4.特性
1)element.getAttribute(attrName):取得元素属性,包括自定义属性。
注意任何元素的所有非自定义属性,都可以通过element.atrribute这中形式来访问。
但style属性通过getAttribute()返回的是CSS文本,通过element.style则返回一个对象。
对于事件处理程序,如onclick特性通过getAttribute()返回的是字符串文本,element.onclick返回的是一个函数。
2)element.setAttribute(name,value):设置元素属性,该属性名会被转换为小写形式。
3)element.removeAttribute(name):移除属性。
5.创建元素
document.createElement(tagName):标签名不区分大小写。
四)Text类型
文本节点由Text类型表示,可以通过nodeValue或者data属性访问Text类型中的值,length属性保存字符串长度。
appendData(text):将 text 添加到节点的末尾。
deleteData(offset, count):从 offset 指定的位置开始删除 count 个字符。
insertData(offset, text):在 offset 指定的位置插入 text。
replaceData(offset, count, text):用 text 替换从 offset 指定的位置开始到 offset+
count 为止处的文本。
splitText(offset):从 offset 指定的位置将当前文本节点分成两个文本节点。
substringData(offset, count):提取从 offset 指定的位置开始到 offset+count 为止
处的字符串
<!-- 没有内容,也就没有文本节点 --> <div></div> <!-- 有空格,因而有一个文本节点 --> <div> </div> <!-- 有内容,因而有一个文本节点 --> <div>Hello World!</div>
1.创建文本节点
document.createTextNode(content):创建一个文本节点
<body> <script> var d = document.createElement("div"); var t = document.createTextNode("Hello world"); d.appendChild(t); document.body.appendChild(d); </script> </body>
2.合并文本节点
如果我们在一个元素上使用多次appendChild()方法追加文本节点,就有可能存在多个文本节点。
此时,我们可以使用Node类型的normalize()方法合并文本节点。element.normalize()
3.分割文本节点
Text类型的spliteText(offset)方法可以分割文本节点
五)Comment类型
注释在DOM中是通过Comment类型表示的,该类型与Text类型继承自相同的基类,
因此它有除了spliteText()方法外所有的字符串操作方法。也可以通过data和nodeValue访问值。
document.createComment(content)创建注释节点
六)Attr类型
元素的特性在DOM中庸Attr类型表示。注意:尽管特性是节点,但它们并不被认为是DOM文档树的一部分。
document.createAttribute(name)