DOM是针对HTML和XML文档的一个API。DOM1级将HTML和XML文档看做一个层次化的节点树,可以使用JavaScript来操作这个节点树,进而改变底层文档的外观和结构。
一.节点层次
1.HTML文档
(1)文档元素:<html> 每个文档只能有一个文档元素,文档中其他所有元素都包含在文档元素中
(2)12种节点类型:继承自一个基类型,每种类型分别表示文档中不同的信息或标记。有 元素节点,特性节点,文档类型节点,注释节点等
2.Node类型
(1)最基本的节点类型时Node,用于抽象表示文档中一个独立的部分。所有类型的继承自Node类型,所以所有的节点类型都共享着基本的属性和方法
nodeType属性,用于表明节点的类型
我自己定义的最基本节点类型NodeType,又定义了一个Document类型:
function NodeType(nodeType){ this.nodeType=nodeType; this.ELEMENT_NODE=1; this.ATTRIBUTE_NODE=2; this.DOCUMENT_NODE=9; } Node.prototype={ constrcutor:NodeType }; var Node=new NodeType("node"); function Document(nodeType){ NodeType.call(this,nodeType); this.nodeType=9; } Document.prototype=new NodeType(); Document.prototype.constructor=Document; var document=new Document("DOCUMENT_NODE"); if(document.nodeType==Node.DOCUMENT_NODE){ alert("Node is document"); } if(document.nodeType==9){ alert("it is true") }
(2)nodeName和nodeValue属性
对于元素节点,nodeName保存元素标签名,nodeValue为null
(3)节点关系
①childNodes属性,指向NodeList对象,用于保存子元素 someNode.childNodes[0]=someNode.childNodes.item(0) 有length属性:someNodes.childNodes.length
将NodeList对象转换为数组:
function convertToArray(nodes){ var array=null; try{ array=Array.prototype.slice.call(nodes.childNodes,0); //非IE }catch(ex){ array=new Array(); for(var i=0,len=nodes.length;i<len;i++){ array.push(node[i]); } } return array; }
②parentNode属性 指向父节点
③previousSibling属性 nextSibling属性 用于访问同一childNodes列表的 前一个和后一个元素
④firstChild: someNode.firstChild=someNode.childNodes[0];
⑤lastChild: someNode.lastChild=someNode.childNodes[someNode.childNodes.length-1];
⑥hasChildNodes():节点包含一个或者多个子节点返回true
⑦owenerDocument属性:指向文档节点 html文档就是指向html节点
(4)操作(子)节点
①插入节点:
appendChild() 用于向childNodes列表末尾添加一个节点
insertBefore() 用于将节点插入到指定的位置,参照节点的前一个节点 insertBefore(newnode,作为参照的节点)
②插入并替换:
replaceChild() 插入新节点并替换原来的节点位置 replaceChild(newNode,要替换的节点)
③只移除不替换:
removeChild()
四种方法都要先取得父节点,如果没有类型不支持子节点,将出错
(5)其他方法
cloneNode() 创建节点的副本
normalize() 处理文本节点
3.Document类型
JS通过Document类型表示文档。document对象是HTMLDocument(继承自Document)的一个实例,表示整个html页面。document对象是window对象的一个属性,可以作为全局对象来访问。
子节点可能是一个DocumentType(<!DOCTYPE>),一个Element(<html>),ProcessingInstruction,Comment
(1)文档的子节点
①documentElement属性:指向<html>元素
document.documentElement=document.childNodes[0]=document.firstchild
②body属性:指向<body>元素
var body=document.body; //取得<body>的引用
③doctype属性:指向<!DOCTYPE> //文档类型说明
(2)文档信息
①title属性:document.title
②页面请求属性
URL属性:包含页面完整的url
domain属性:只包含页面的域名
referrer属性:保存链接到当前页面的那个页面的url
只有domain属性可以设置:可以通过设置document.domain相同,实现与内嵌框架的通信,访问对方的JS对象
(3)查找元素:取得某个或某组元素的引用
①getElementById():区分大小写
<div id="myDiv">text</div> var div=document.getElementById("myDiv"); //取得<div>元素的引用
注:表单中的name不要与其他元素的ID相同,会有怪癖
②getElementsByTagName():接受标签名,返回一个HTMLCollection对象,类似于NodeList。可以用[]或item()访问项
var images=document.getElementsByTagName(“img”); //取得页面中所有<img>元素 alert(images[0].src);
HTMLCollection对象的一个方法:namedItem() 通过name特性取得集合中的项
var myImage=images.namedItem(“name”);
按名称访问项:
var myImage=images[0]; //后台调用item()
var myImage=images[“name”]; //后台调用namedItem()
取得文档中所有元素:var allElements=document.getElementsByName(“*");
③getElementsByName():返回带有给定name的所有元素
多用于取得单选按钮 var radios=document.getElementsByName(“name”);
namedItem()只取得第一项
(4)特殊集合
document.anchors
document.applets
document.forms
document.images
document.links
(5)DOM一致性检测
document.implementation.hasFeature(“XML”,"1.0”) //支持给定的名称和版本号返回true
(6)文档写入
write():原样写入
writeln():会在字符串末尾添加换行符(/n)
open()
close()
document.write(("<strong>"+new Date()).toString()+"</strong>");
包含</script>标签时:document.write("</script>”);
文档加载结束后调用document.write()将重写真个页面
4.Element类型
Element类型用于表现XML或HTML元素,提供了对元素标签名,子节点及特性的访问
要访问元素的标签名可以使用nodeName属性和tagName属性:document.getElementById(“myDiv”).nodeName;
在HTML中,标签名始终都是大写
if(element.tagName.toLowerCase()=="div"){ //操作 }
两种方法访问元素的特性:通过对象属性访问和通过特定方法取得特性
(1)HTML元素属性
HTML元素都由HTMLElement类型表示,HTMLElement直接继承自Element并添加了一些属性。这些属性分别对应于元素的标准特性:
id,title,lang,dir,className(因为class是ECMAScript中的保留字,所以定义为className,对应class特性)
例:
<div id=”myDiv” class=”bd” title=”Body text” lang=”en” dir=”ltr”></div>
var div=document.getElementById(“myDiv”);
alert(div.id); //”myDiv” 元素的属性对应元素的特性
div.id=”newid”; //修改
(2)取得特性
①getAttribute()
例:div.getAttribute(“class”);
由于在取得style和时间处理程序(如onclick)的时候,通过属性和getAttribute方法得到的值不同。
一般指使用对象的属性,在取得自定义特性的时候才使用getAttribute()f方法
(3)设置特性
setAttritube(“要设置的特性名",”值”)
设置的特姓名统一转换为小写
removeAttribute() 删除特性
(4)attributes属性
包含一个对象,这个对象将特性用节点表示,节点的nodeName是特性的名称,节点的nodeValue是特性的值
var id=element.attributes[“id”].nodeValue;
多用于遍历元素的特性:
function outputAttributes(element){ var myArray=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; if(element.attributes.specified){ myArray.push(attrName+"="+attrValue+"="); } } return myArray.join(" "); }
(5)创建元素
document.createElement()
例:
var div=document.createElement(“div”);
div.id=”myDiv”;
div.className=”box”;
document.body.appendChild(“div”);
(6)元素的子节点
元素也支持getElementsByTagname()方法
var ul=document.getElementsById(“myList”);
var li=ul.getElementsByTagName(“li”);
5.Text类型
文本节点包含可以照字面解释的纯文本内容
nodeValue和data属性包含节点中的文本
节点的length属性中保存节点中字符的数目
(1)创建文本节点
document.createTextNode()
例:
var element=document.createElement(“div”);
element.className=”message”;
var textNode=document.createElement(“Hello world”);
element.appendChild(“textNode”);
document.body.appendChild(“element”);
(2)规范化文本节点
normalize():将所有节点合并为一个节点
(3)分割文本节点
splitText():用于从文本节点中提取数据
6.Comment类型
createComment()
7.CDATASection类型
8.DocmentType类型
9.DocumentFragment类型
10.Attr类型
二.DOM操作技术
1.动态脚本
①外联样式的动态脚本
function loadScript(url){ var script=document.createElement("script"); script.type="text/javascript"; script.src=url; document.body.appendChild(script); } laodScript("my.js");
②内敛样式的动态脚本
function loadScript(code){ var script=document.createElement("script"); script.type="text/javascript"; try{ script.appendChild(document.createTextNode(code)); }catch(ex){ script.text=code; //IE将script视为一个特殊的节点,不允许访问其子节点,但有一个text属性 } document.body.appendChild(script); }
2.动态样式
①外联动态样式
function loadStyle(url){ var link=document.createElement("link"); link.rel="stylesheet"; link.type="text/css"; link.href=url; var head=document.getElementsByTagName("head")[0]; head.appendChild(link); }
②内敛动态样式
function loadStyle(css){ var style=document.createElement("style"); style.type="text/css"; try{ style.appendChild(document.createTextNode(css)); }catch(ex){ style.stylesheet.cssText=css; } var head=document.getElementsByTagName("head")[0]; head.appendChild(style); } loadStyle("body{background-color:blue}");
3.操作表格
用DOM创建表格
<table border=”1” width=”100%”>
<tbody>
<tr>
<td>cell1,1</td>
<td>cell2,1</td>
</tr>
<tr>
<td>cell1,2</td>
<td>cell2,2</td>
</tr>
</tbody>
</table>
var table=document.createElement("table"); table.border=1; table.width="100%"; //创建tbody var tbody=document.createElement("tbody"); table.appendChild(tbody); //创建第一行 tbody.insertRow(0); tbody.rows[0],insertCell(0); tbody.rows[0].cells[0].appendChild(document.createTextNode("cell1,1")); tbody.rows[0].insertCell(1); tbody.rows[0].cells[1].appendChild(document.createTextNode("cell2,1")); //创建第二行 tbody.insertRow(1); tbody.rows[1],insertCell(0); tbody.rows[1].cells[0].appendChild(document.createTextNode("cell1,2")); tbody.rows[1].insertCell(1); tbody.rows[1].cells[1].appendChild(document.createTextNode("cell2,2")); document.body.appendChild(table);
4.使用NodeList
NodeList,NamedNodeMap,HTMLCollection三个集合都是动态的
要减少使用,每次访问都要运行一次基于文档的查询,可以将其值保持起来len=divs.length