Node类型
DOM1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现。因此所有节点类型都共享这相同的基本属性和方法。每个节点类型都有一个nodeType属性,用于表明节点的类型。由12个数值常亮来表示。
Node.ELEMENT_NODE(1);
Node.ATTUIBUTE_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);
确定节点的类型:
if(someNode.nodeType == Node.ELEMENT_NODE){//在IE中无效
alert("node is an element");
}
//IE没有公开Node类型的构造函数
if(someNode.nodeType == 1){//所有浏览器适用
alert("node is an element");
}
并不是所有节点类型都受到web浏览器的支持,开发人员最常用到的是元素和文本节点。
- nodeName保存的是元素的标签名,而nodeValue的值则始终为null.
if(someNode.nodeType == 1){
value = someNode.nodeName;
}
节点类型
每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,但他不是Array的实例。他实际上是基于DOM结构动态执行查询的结果。因此DOM结构的变化能够自动反映在NodeList对象中。
访问NodeList中的节点:
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
将nodeList对象转换成数组:
function convertToArray(nodes){
var array = null;
try{
array = Array.prototype.slice.call(nodes,0);//IE8及更早版本无效
}catch(ex){
array = new Array();
for(var i=0,len=nodes.length;i<len;i++){
array.push(nodes[i]);
}
}
return array;
}
每个节点都有一个parentNode属性,指向文档树中的父节点。包含在childNodes列表中的每个节点相互之间都是同胞节点。通过previousSibling和nextSibling属性访问前后兄弟节点。
父节点的firstChild和lastChild分别指向childNodes列表中的第一个和最后一个节点。
hasChildNodes()方法判断有没有子节点。
所有节点还有一个属性ownerDocument,指向表示整个文档的文档节点。
操作节点
appendChild():新增节点并返回新增的节点。
var returnedNode =someNode.appendChild(newNode);
alert(returnedNode == newNode);//true
如果传入到appendChild中的节点已经是文档的一部分,那么就会将该节点从原来的位置转移到新位置。任何DOM节点不能同时出现在文档中的多个位置上。
insertBefore(要插入的节点,参照节点):返回新插入的节点。如果第二个参数为null,则与appendChild()执行相同的操作。
replaceChild(要插入的节点,要替换的节点):返回要替换的节点。
removeChild(要移除的节点):返回要移除的节点。
其他方法
有两个方法是所有类型的节点都有的。
cloneNode():创建调用这个方法的节点的一个完全相同的副本。接收一个布尔值参数,表示是否执行深复制。true表示执行深复制,复制节点及整个子节点树。false表示只复制节点本身。复制后的返回的节点属于文档所有,但并没有为它指定父节点。要通过appendChild().insertBefore()等方法将它添加到文档中。
注:cloneNode()方法不会复制添加到DOM节点中的javascript属性,例如事件处理程序。这个方法只复制特性。
normalize():处理文档树中的节点。如果该节点的后代节点中有空文本节点,则删除它,如果找到相邻的文本节点,则将他们合并成一个文本节点。
Document类型
Document类型表示文档。nodeType的值为9,nodeName的值为“#document”.可以表示HTML页面或其他基于XML的文档。
var html = document.documentElement;//取得对<html>的引用
alert(html === document.childNodes[0]);//true
alert(html === document.firstChild);
var body = document.body;//取得对<body>的引用
var doctype = document.doctype;//取得对<!DOCTYPE>的引用。不同浏览器差异很大。很少使用
多数情况下不必在document对象上调用appendChild(),removeChild()等方法。因为文档类型是只读的。而且它只能有一个元素子节点。
文档信息
作为HTMLDocument的一个实例,document对象还有一些标准的Document对象所没有的属性。
var orginanlTitle = document.title;//取得文档标题
document.title = "new page title";
与网页请求相关的3个属性,这些属性都保存在请求的HTTP头部。
URL:即地址栏中显示的URL
domain:页面的域名
referrer:链接到当前页面的那个页面的URL。即来源URL。
var url = document.URL;
var domain = document.domain;
var referrer = document.referrer;
这三个属性只有domain是可以设置的。且只能设置为原URL中包含的一个子域名。例如p2p.wrox.com只能将domain设置为wrox.com。
查找元素
- getElementById(“id”):如果页面中多个元素的ID值相同,则只返回文档中第一次出现的元素。
IE7及最早版本有个“怪癖”:name特性与给定ID匹配的表单元素(input,textarea)也会被该方法返回。而且该元素在文档中位于给定ID的元素前面,那么IE就会返回那个表单元素。
<input type="text" name="mydiv" value="text field">
<div id="mydiv">a div</div>
在IE7中调用document.getElementById(“mydiv”)会返回元素。
- getElementsByTagName(标签名):返回包含零或多个元素的NodeList。在HTML文档中,这个方法会返回HTMLCollection对象。该对象与NodeList对象类似,
var images = document.getElementsByTagName("img");
alert(images.length);
alert(images[0].src);//后台执行等于下面这句
alert(images.item(0).src);
//可以通过namedItem()方法取得集合中特定name的项
var myImage = images.namedItem("myImage");
var myImage = images["myImage"];//后台执行等于上面这句
为了与既有HTML兼容,传给getElementsByTagName的标签名是不区分大小写的。
- getElementsByName():返回带有给定name特性的所有元素。最长使用此方法的情况是取得单选按钮。该方法也是返回一个HTMLColection对象。
特殊集合
document对象还有一些特殊的集合。这些集合都是HTMLCollection对象
document.anchors:包含文档中所有带有name特性的元素。
document.applets:包含文档中所有元素。不建议使用
document.forms:包含文档中所有元素。
document.images:包含文档中所有元素。
docuemnt.links:包含文档中所有带href特性的元素
文档写入
将输出流写入到网页中。
write():
writen():
open():打开网页的输出流
close():关闭网页的输出流
动态包含外部文件:
<script type="text/javascript">
document.wirte("<script type=\"text/javascript\" src=\"file.js\">"+
"<\/script>");
</script>
Element类型
用于表现XML或HTML元素。提供了对元素标签名、子节点及特性的访问。具有如下特性:
nodeType值为1,nodeName的值为元素的标签名。
var div = document.getElementById("mydiv");
alert(div.tagName);//"DIV"
alert(div.tagName == div.nodeName);//true
HTML元素
所有HTML元素都由HTMLElement类型表示。HTMLElement类型继承自Element类型并添加了一些属性。
id:元素在文档中的唯一标识符
title:有关元素的附加说明信息。一般通过工具提示条显示出来。
lang:元素内容的语言代码,很少使用。
dir:语言的方向。“ltr”表示从左至右,”rtl”表示从右至左。很少使用。
className:与元素的class特性对应。
<div id="mydiv" class="bd" title="body text" lang="en" dir="ltr"></div>
还有三个方法,用于操作HTMLElement属性:
getAttribute():得到特定属性值
setAttribute():设置某个属性值
removeAttribute():删除属性
var mydiv = document.getElementById("mydiv");
div.setAttribute("class","ft");
div.getAttribute("id");
div.removeAttribute("class");
attributes属性
Element类型是使用attributes属性的唯一一个DOM节点类型,它包含一个NamedNodeMap对象,该对象拥有以下方法:
1. getNamedItem(name):返回nodeName属性等于name的节点。
2. removeNamedItem(name):移除nodeName属性等于name的节点
3. setNamedItem(node):向列表中添加节点。
4. item(pos):返回位于数字pos位置处的节点。
var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;
以上方法不常用,不过在遍历元素特性时可以用到。
var outputAttributes(element){
var pairs = new Array(),
attrName,
attrValue,
i,
len;
for(i=0,len=element.attributes.length;i<len;i++){
attrName = element.attributes[i].nodeName;
attrValue = element.attributes[i].nodeValue;
//让它只返回指定的特性即html中指定的相应特性或者通过setAttribute()设置了该特性
if(element.attributes[i].specified){
pairs.push(attrName = "=\"" = attrValue + "\"");
}
}
return pairs.join(" ");
}
创建元素
var div = document.createElement("div");
div.id="myNewDiv";
div.className = "box";
document.body.appendChild(div);
在IE7中可以使用另一种方式
var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div>");
if(client.browser.ie && client.browser.ie<=7){
var iframe = document.createElement("<iframe name=\"myframe\"></iframe>");
var input = document.createElement("<input type=\"checkbox\">");
var button = document.createElement("<button type=\"reset\"></button>");
var radio1= document.createElement("<input type=\"radio\" name=\"choice\" value=\"1\">");
var radio2= document.createElement("<input type=\"radio\" name=\"choice\" value=\"2\">");
}
元素的子节点
<ul id="mylist">
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
在IE中,
- 元素有3个子节点,分别是3个
- 元素。在其他浏览器中,
- 元素会有7个元素:3个
- 元素4个文本节点(表示
- 元素之间的空白符)。如果像下面这样将元素间的空白符删除。那么所有浏览器都会返回相同数目的子节点。
<ul id="mylist"><li>item1</li><li>item2</li><li>item3</li></ul>
在遍历这些子节点的属性时,通常先检查下nodeType属性。
for(var i=0,len=element.childNodes.length;i<len;i++){
if(element.childNodes[i].nodeType == 1){//表示元素节点
//do something
}
}
Text类型
包含的是可以照字面解释的纯文本节点。纯文本中可以包含转义后的HTNL字符,但不能包含HTML代码。
Text节点具有以下特征。
nodeType的值为3.
nodeName的值为“#text”;
nodeValue的值为节点所包含的文本。
可以通过nodeValue属性或data属性访问Text节点中包含的文本。使用下列方法可以操作节点中的文本。
appendData(text):将text添加到节点的末尾。
deleteData(offset,count):从offset指定的位置开始删除count个字符。
insertData(offset,text):在offset指定的位置插入text.
repalaceData(offset,count,text):用text替换从offset指定的位置开始到offset+count为止处的文本。
splitText(offset):从offset指定的位置将当前文本分成两个文本节点。
subStringData(offset,count):提取从offset指定的位置开始到offset+count为止处的字符串。
- document.createTextNode(文本):创建文本节点.
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类型
注释在DOM中是通过Comment类型来表示的。具有如下特征:
nodeType的值为8;nodeName的值为#comment。nodeValue是注释的内容。
Comment类型与Text类型继承自相同的基类,因此他拥有splitText()之外的所有字符串操作方法。也可以通过nodeValue或data属性来取得注释的内容。
<div id="mydiv"><!--A comment --></div>
var div = document.getElementById("mydiv");
var comment = div.firstChild;
alert(comment.data);// A comment
document.createComment(“comment”):创建注释节点
CDATASection类型
此类型只针对XML文档,表示的是CDATA区域。与Comment类似,CDATASection类型继承自Text类型,因此拥有除splitText()之外的所有字符串操作方法。
CDATA区域只会出现在XML文档中,因此多数浏览器都会把CDATA区域错误的解析为Comment或Element.
<div id="mydiv"><![CDATA[This is some content.]]</div>
四大主流浏览器不能正确的解析CDATASection节点。在真正的XML文档中,可以使用document.createCDataSection()来创建CDATA区域。
Attr类型
元素的特性用Attr类型来表示。此类型有3个属性,name,value,speciied(区别特性是在代码中指定的还是默认的)
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
动态脚本
指的是在页面加载时不存在,但将来的某一时刻通过修改DOM动态添加的脚本。有两种方式:插入外部文件和直接插入javascript代码。
<script type="text/javascript" src="client.js"></srcript>
整个过程可以用以下函数来表示。
function landScriptString(code){
var script = document.createElement("script");
script.type = "text/javascript";
try{
script.appendChild(document.createTextNode(code));
}catch(ex){
script.text = code;
}
document.body.appendChild(script);
}
以这种方式加载的代码会在全局作用域中执行。相同于将字符串传递给eval()是一样的。
动态样式
所谓动态样式是指在页面加载完后动态添加到页面中的。
<link rel="stylesheet" type="text/css" href="styles.csss">
动态样式加载过程如下函数所示:
var style = document.createElement("style");
style.type = "text/css";
try{
style.appendChild(document.createTextNode("body{background-color:red}"));
}catch(ex){
style.stylesheet.cssText = "body{background-color:red}";//针对ie
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
操作表格
元素的属性和方法:caption:保存着对元素的指针
tBodies:是一个元素的HTMLCollection.
tFoot:保存着对元素的指针
tHead:
rows:是一个表格中所有行的HTMLCollection.
createTHead():创建元素,将其放到表格中,返回其引用。
createTFoot():
createCaption():
deleteTHead():
deleteTFoot():
deleteRow(pos):删除指定位置的行
insertRow(pos):向rows集合中的指定位置插入一行。
为元素添加的属性和方法:
rows:保存着元素中行的HTMLCollection。
deleteRow(pos):
insertRow(pos):
为tr元素添加的属性和方法:
cells:保存着元素中单元格的HTMLCollection.
deleteCell(pos):删除指定位置的单元格
insertCell(pos):向Cells集合中的指定位置插入一个单元格。
使用NodeList
NodeList,NamedNodeMap,HTMLCollection:这三个集合都是动态的。每当文档结构发生变化时,他们都会得到更新。
一般来说,应该尽量减少访问NodeList的次数,因为每次访问NodeList都会运行一次基于文档的查询。所以可以考虑将从NodeList中取得的值缓存起来。