DOM 节点层次

DOM(文档对象模型)是针对 HTML 和 XML 文档的一个 API

DOM 可以将任何 HTML 或 XML 文档描绘成一个由多层节点构成的结构。

<html>元素 称之为文档元素,文档元素是文档的最外层元素

Node类型

DOM1 级定义了一个 Node 接口,该接口将由 DOM 中的所有节点类型实现

JavaScript 中的所有节点类型都继承自 Node 类型,因此所有节点类型都共享着相同的基本属性和方法。

每个节点都有一个 nodeType 属性,用于表明节点的类型。会以数值的方式打印出来

  1. Node.ELEMENT_NODE;
  2. Node.ATTRIBUTE_NODE;
  3. Node.TEXT_NODE;
  4. Node.CDATA_SECTION_NODE;
  5. Node.ENTITY_REFERENCE_NODE;
  6. Node.ENTITY_NODE;
  7. Node.PROCESSING_INSTRUCTION_NODE;
  8. Node.COMMENT_NODE;
  9. Node.DOCUMENT_NODE;
  10. Node.DOCUMENT_TYPE_NODE;
  11. Node.DOCUMENT_FRAGMENT_NODE;
  12. Node.NOTATION_NODE。

nodeNamenodeValue属性

对于元素节点,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 属性,该属性指向文档树中的父节点。

通过使用列表中每个节点的 previousSiblingnextSibling 属性,可以访问同一列表中的其他节点

列表中第一个节点的 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"; 

URLdomainreferrer

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"