DOM(文档对象模型)是针对 HTML 和 XML 文档的一个 API
DOM 可以将任何 HTML 或 XML 文档描绘成一个由多层节点构成的结构。
<html>
元素 称之为文档元素,文档元素是文档的最外层元素
Node类型
DOM1 级定义了一个 Node 接口,该接口将由 DOM 中的所有节点类型实现。
JavaScript 中的所有节点类型都继承自 Node 类型,因此所有节点类型都共享着相同的基本属性和方法。
每个节点都有一个 nodeType 属性,用于表明节点的类型。会以数值的方式打印出来
- Node.ELEMENT_NODE;
- Node.ATTRIBUTE_NODE;
- Node.TEXT_NODE;
- Node.CDATA_SECTION_NODE;
- Node.ENTITY_REFERENCE_NODE;
- Node.ENTITY_NODE;
- Node.PROCESSING_INSTRUCTION_NODE;
- Node.COMMENT_NODE;
- Node.DOCUMENT_NODE;
- Node.DOCUMENT_TYPE_NODE;
- Node.DOCUMENT_FRAGMENT_NODE;
- Node.NOTATION_NODE。
nodeName
和 nodeValue
属性
对于元素节点,nodeName 中保存的始终都是元素的标签名,而 nodeValue 的值则始终为 null
节点关系
每个节点都有一个 childNodes
属性,其中保存着一个 NodeList 对象。
NodeList 是一种类数组 对象,用于保存一组有序的节点,可以通过位置来访问这些节点。NodeList 是动态的,随节点变化变化。
访问NodeList 对象可以通过方括号,也可以使用 item() 方法。
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
对 arguments 对象使用 Array.prototype.slice()方法可以 将其转换为数组
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
每个节点都有一个 parentNode
属性,该属性指向文档树中的父节点。
通过使用列表中每个节点的 previousSibling
和 nextSibling
属性,可以访问同一列表中的其他节点
列表中第一个节点的 previousSibling 属性 值为 null,而列表中最后一个节点的 nextSibling 属性的值同样也为 null
hasChildNodes()
这个方法在节点包含一或多个子节点的情况下返回 true
操作节点
appendChild()
用于向 childNodes 列表的末尾添加一个节点,更新完成后,appendChild() 返回新增的节点
如果传入到 appendChild()
中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置 转移到新位置。
insertBefore()
接受两个参数:要插入的节点和作为参照的节点
插入节点后,被插 入的节点会变成参照节点的前一个同胞节点(previousSibling),同时被方法返回。
如果参照节点是 null,则 insertBefore()与 appendChild()执行相同的操作
//插入后成为最后一个子节点
returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true
replaceChild()
接受的两个参数:要插入的节点和要替换的节点
要替换的节点将由这个 方法返回并从文档树中被移除,同时由要插入的节点占据其位置。被替换的节点仍然还在文档中,但它在文档中已经没有了自己的位置。
//替换第一个子节点
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);
//替换最后一个子节点
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
removeChild()
接受一个参数:要移除的节点
//移除第一个子节点
var formerFirstChild = someNode.removeChild(someNode.firstChild);
//移除最后一个子节点
var formerLastChild = someNode.removeChild(someNode.lastChild);
通过 removeChild()移除的节点仍然为文档所有,只不过在 文档中已经没有了自己的位置
其他方法
有两个方法是所有类型的节点都有的
第一个就是 cloneNode()
,用于创建调用这个方法的节点 的一个完全相同的副本。
cloneNode()方法接受一个布尔值参数,表示是否执行深复制。
在参数为 true 的情况下,执行深复制,也就是复制节点及其整个子节点树;
在参数为 false 的情况下,执行浅复制, 即只复制节点本身。
<ul>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
var myList=document.getElementsByTagName('ul')[0]
//深复制 复制了ul自己下面的所有子节点
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length);
//浅复制 只复制ul一个本身元素 子节点没有复制
var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0
第二个方法是**normalize()
**,这个方法唯一的作用就是处理文档树中的文本节点
如果找到了 空文本节点,则删除它;如果找到相邻的文本节点,则将它们合并为一个文本节点。
Document类型
document 对象是 HTMLDocument(继承 自 Document 类型)的一个实例,表示整个 HTML 页面。
document 对象是 window 对象的一个 属性,因此可以将其作为全局对象来访问。
文档的子节点
document.documentElement
取得对<html>
的引用
document.body
取得对<body>
的引用
文档信息
<title>
//取得文档标题
var originalTitle = document.title;
//设置文档标题
document.title = "New page title";
URL
、domain
和 referrer
URL
属性 中包含页面完整的 URL
domain
属性中只包含页面的域名
referrer
属性中则保存着链接到当前页面的那个页面的 URL。
在没有来源页面的情况下,referrer 属性中可能 会包含空字符串。
//取得完整的 URL
var url = document.URL;
//取得域名
var domain = document.domain;
//取得来源页面的 URL
var referrer = document.referrer;
查找元素
getElementById()
ID属性
getElementsByTagName()
标签名字 NodeName
getElementsByName()
name属性
<ul>
<li><input type="radio" value="red" name="color" id="colorRed">
<label for="colorRed">Red</label></li>
<li><input type="radio" value="green" name="color" id="colorGreen">
<label for="colorGreen">Green</label></li>
<li><input type="radio" value="blue" name="color" id="colorBlue">
<label for="colorBlue">Blue</label></li>
</ul>
ID 的 作用在于将元素应用到每个单选按钮,而 name 特性则用以确保三个值中只有一个被发送给浏览器
特殊集合
- document.anchors,包含文档中所有带 name 特性的元素;
- document.applets,包含文档中所有的元素,因为不再推荐使用元素, 所以这个集合已经不建议使用了;
- document.forms,包含文档中所有的元素,与 document.getElementsByTagName("form") 得到的结果相同;
- document.images,包含文档中所有的
<img>
元素,与 document.getElementsByTagName ("img")得到的结果相同 - document.links,包含文档中所有带 href 特性的元素
文档写入
write()
、writeln()
、open()
和 close()
write()会原样写入,而 writeln()则会 在字符串的末尾添加一个换行符(\n)
open()和 close()分别用于打开和关闭网页的输出流。
Element类型
Element 类型就要算是 Web 编程中最常用的类型了。
Element 类型用 于表现 XML 或 HTML元素,提供了对元素标签名、子节点及特性的访问。
也可以用tagName来获取标签名称
<div id="myDiv"></div>
var div = document.getElementById("myDiv");
alert(div.tagName); //"DIV"
alert(div.tagName == div.nodeName); //true
if (element.tagName == "div"){ //不能这样比较,很容易出错!
//在此执行某些操作
}
if (element.tagName.toLowerCase() == "div"){ //这样最好(适用于任何文档)
//在此执行某些操作
}
HTML元素
这些属性分别对应于每个 HTML 元素中都存在的下列标准特性。、
- id,元素在文档中的唯一标识符。
- title,有关元素的附加说明信息,一般通过工具提示条显示出来。
- lang,元素内容的语言代码,很少使用。
- dir,语言的方向,值为"ltr"(left-to-right,从左至右)或"rtl"(right-to-left,从右至左), 也很少使用。
- className,与元素的class 特性对应,即为元素指定的CSS类。没有将这个属性命名为class, 是因为 class 是 ECMAScript 的保留字
<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>
获取上面元素的信息
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";
获取特征
getAttribute()
因为 id 和 align 在 HTML 中是的公认特性
自定义特性无法直接通过对象身上属性获取
<div id="myDiv" align="left" my_special_attribute="hello!"></div>
alert(div.id); //"myDiv"
alert(div.my_special_attribute); //undefined
alert(div.align); //"left"
也不能这样为DOM元素添加一个自定义属性
div.mycolor = "red";
alert(div.getAttribute("mycolor")); //null
var div = document.getElementById("myDiv");
//getAttribute
alert(div.getAttribute("id")); //"myDiv"
alert(div.getAttribute("class")); //"bd"
alert(div.getAttribute("my_special_attribute")) //"hello
设置特性
setAttribute()
这个方法接受两个参数:要设置的特性名和 值
如果特性已经存在,setAttribute()会以指定的值替换现有的值
如果特性不存在,setAttribute() 则创建该属性并设置相应的值
通过这个方法设置的 特性名会被统一转换为小写形式
div.setAttribute("id", "someOtherId");
div.setAttribute("class", "ft");
移除特性
removeAttribute()
这个方法用于彻底删除元素的特性。调用这个方 法不仅会清除特性的值,而且也会从元素中完全删除特性
div.removeAttribute("class")
attributes属性
Element 类型是使用 attributes 属性的唯一一个 DOM 节点类型。
元素的每一个特性都由一个 Attr 节 点表示,每个节点都保存在 NamedNodeMap 对象中。
-
getNamedItem(name):返回 nodeName 属性等于 name 的节点;
-
removeNamedItem(name):从列表中移除 nodeName 属性等于 name 的节点;
-
setNamedItem(node):向列表中添加节点,以节点的 nodeName 属性为索引;
-
item(pos):返回位于数字 pos 位置处的节点。
创建元素
document.createElement()
可以创建新元素
这个方法只接受一个参数:这个方法只接受一个参数,这个方法只接受一个参数
元素的子节点
var ul = document.getElementById("myList");
var items = ul.getElementsByTagName("li");
这里<ul>
的后代中只包含直接子元素。不过,如果它包含更多层次的后代元素,那 么各个层次中包含的<li>
元素也都会返回
Text类型
可以通过 nodeValue 属性或 data 属性访问 Text 节点中包含的文本,这两个属性中包含的值相同。
创建文本节点
document.createTextNode()
创建新文本节点
接受一个参数:要插入节点 中的文本
document.createTextNode("Hello world!");
规范化文本节点
normalize()
能够将相邻文本节点合并的方法
var element = document.createElement("div");
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
var anotherTextNode = document.createTextNode("Yippee!");
element.appendChild(anotherTextNode);
document.body.appendChild(element);
//两个文本节点
alert(element.childNodes.length); //2
element.normalize();
//合成为一个文本节点
alert(element.childNodes.length); //1
alert(element.firstChild.nodeValue); // "Hello world!Yippee!"
分割文本节点
splitText()
按照指定的位置分割 nodeValue 值
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
alert(element.firstChild.nodeValue); //"Hello"
alert(newNode.nodeValue); //" world!"
alert(element.childNodes.length); //2
Comment类型
用于代码块加注释
Comment 类型与 Text 类型继承自相同的基类,因此它拥有除 splitText()之外的所有字符串操 作方法。
document.createComment()
为其传递注释文本也可以创建注释节点
Attr类型
最常使用的是 getAttribute()
、setAttribute()
、remveAttribute()
Attr 对象有 3 个属性:name、value 和 specified
name 是特性名称(与 nodeName 的 值相同),value 是特性的值(与 nodeValue 的值相同),而 specified 是一个布尔值,用以区别特 性是在代码中指定的,还是默认的。
使用 document.createAttribute()
并传入特性的名称可以创建新的特性节点
var attr = document.createAttribute("align");
attr.value = "left";
element.setAttributeNode(attr);
alert(element.attributes["align"].value); //"left"
alert(element.getAttributeNode("align").value); //"left"
alert(element.getAttribute("align")); //"left"