DOM
- DOM可以将任何HTML文档或XML文档描绘成一个由多层次节点构成的结构。节点分为不同类型,每个节点拥有各自特点、数据和方法。
- 文档元素是文档最外层元素,文档中的其他元素都包含在文档元素中。每个文档只能有一个文档元素。
- 每一段标记都可以通过树中的一个节点来表示:HTML元素通过元素节点表示,特性通过特性及节点表示,文档类型通过文档类型节点表示,注释通过注释节点表示。共12种,这些类型都继承自一个基类型。
Node类型
nodetype属性
- 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);
通过以上常量,可确定节点类型
if(somNode.nodeType == 1){
console.log("Node is an element.");
}
- nodeName和nodeValue属性
if(somNode.nodeType == 1){//检测节点类型
value = someNode.nodeName; //nodeName的值是元素标签名 nodeValue的值为null
}
每个节点都有一个childNode属性,其中保存着一个类数组的NodeList对象。保存一组有序节点,有length属性,但不是Array实例。是基于DOM动态查询的结果。
- 将NodeList转换为数组
function converToArray(nodes){ var array = null; try{ array = Array.prototype.slice.call(nodes,0);//针对非IE浏览器 }catch(ex){ //若导致错误,手动创建 array = new Array(); for(var i=0, len=nodes.length; i<len; i++){ array.push(node[i]); } } return array; }
- 将NodeList转换为数组
每个节点都有一个parentNode属性,指向文档树的父节点。包含在childNode列表中的所有节点具有相同父节点。每个节点相互间为同胞节点。通过使用previousSibling和nextSibling属性,可以访问同一列表其他节点。列表中第一个节点previousSibling值为null,最后一个节点 nextSibling值为null。hasChildNodes()方法在节点包含一或多个子节点时返回true。
操作节点
- 末尾添加:appendChild()方法,向childNodes列表末尾添加一个节点,完成后返回新增节点。
var returnedNode = someNode.appendChild(newNode); console.log(returnedNode == newNode);//true console.log(someNode.lastChild == newNode);//true
若传入节点已是childNodes列表的一部分,则该节点从原来的地方转移到末尾。
插入:insertBefore()方法,接收两个参数:待插入节点和参照节点。返回待插入节点。
returnedNode = someNode.insertBefore(newNode,someNode.last); console.log(newNode == someNode.childNodes[someNode.childNodes.length-2]);//true
替换:replaceChild()方法,接收两个参数:要插入的节点和要替换的节点。返回要替换的节点。被替换的节点仍归文档所有,只是在文档中没有了自己的位置
- 移除:removeChild()方法,接收一个参数,即要移除的节点。返回要移除的节点。被删除的节点仍归文档所有,只是在文档中没有了自己的位置。
创建一个完全相同的副本:cloneChild()方法。接收一个布尔值参数。true代表深复制,复制节点及整个子节点树;false代表浅复制,只复制节点本身。
var deepList = myList.cloneNode(true); console.log(deepList.childNodes.length);//子节点个数
处理文本树中的文本节点:normalize(),某个节点调用该方法,就会在该节点的后代查找,若找到空文本节点则删除;若找到相邻文本节点,则合并为一个。
- 末尾添加:appendChild()方法,向childNodes列表末尾添加一个节点,完成后返回新增节点。
Document类型
- Document类型表示文档。document对象是HTMLDocument的一个实例,表示整个HTML页面。document对象是window对象的一个属性。
- 特征:
- nodeType值为9;
- nodeName值为”#document”;
- nodeValue值为null;
- parentNode值为null;
- ownerDocument值为null;
- 子节点可能是DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction或Comment。
- 文档子节点
//取得对<html>的引用
var html = document.documentElement;
console.log(html === document.childNode[0]);//true
console.log(html === document.firstChild); //true
//取得对<body>的引用
var body = document.body;
//取得对<!DOCTYPE>引用 浏览器对其支持差别很大
var doctype = document.doctype;
- 文档信息
//取得标题文档
var orginalType = document.title;
//设置文档标题
document.title = "New page title";
//取得完整URL
var url = document.URL;
//取得域名
var domain = document.domain;
//取得来源页面的URL
var referrer = document.referrer
URL与domain属性是关联的。eg:document.URL等于http://www.wrox.com/wileyCDA/,那么document.domain等于www.wrox.com。
查找元素
DOM常见应用:获取某个或某组元素的引用,然后执行操作。getElemenstById()
<div id="myDiv">some text</div> var div = document.getElementsById("myDiv"); //取得<div>元素的引用
getElementsByTagName()
var imges = document.getElementsByTagName("img"); //HTML文档会返回一个HTMLCollection对象 console.log(imges.length);//输出HTML图像数量 console.log(imges[0].src);//输出第一个图像元素的src特性
namedItem()
<img src="myimage.gif" name="myImage"> var myImage = imges.namedItem("myImage");//通过name特性取得集合中的项 var myImage = imges["myImage"];//也可通过中括号访问
取得文档中的所有元素
var allElements = document.getElementsByTagName("*");
getElementsByName()
返回带有给定name特性的所有元素。常用来取得单选按钮。<ul> <li><input type="radio" value="red" name="name" id="colorRed"> <lable for="colorRed">Red</lable></li> <li><input type="radio" value="blue" name="name" id="colorBlue"> <lable for="colorBlue">Blue</lable></li> </ul> var radios = document.getElementsByName("color");//取得所有单选按钮
- 特殊集合
document.anchors
,包含文档中带有name属性的<a>
元素;document.forms
,包含文档中所有<form>
元素,与document.getElementsByTagName("form")
得到的结果相同document.images
,包含文档中所有<image>
元素,与document.getElementsByTagName("image")
得到的结果相同document.links
,包含文档中所有带herf特性的<a>
元素。
Element类型
特征
- nodeType值为1;
- nodeName值为元素的标签名;
- nodeValue值为null;
- parentName可能是Document或Element;
- 子节点可能是Element、Text、Comment、ProcessingInstruction、CDATASection或EnityReference。
if(element.tagName.toLowerCase() == "div"){ //在此执行某些操作 }
- HTML元素。每个HTML元素中都存在下列标准特性。
- id,元素在文档唯一标识符
- title,有关元素附加说明信息,一般通过工具条显示出来。
- className,与元素的class特性对应,,即为元素指定css类。
这些属性都可用来取得或修改相应值。
<div id="myDiv" class="bd" title="Body text"></div>
var div = document.getElementById("myDiv");
console.log(div.id);//"myDiv"
console.log(div.className);//"bd"
console.log(div.title);//"Body text"
div.id = "sonmeOtherId";//修改
取得特性:getAttribute():特性名与实际特性名相同
var div = document.getElementById("myDiv"); console.log(div.getAttribute("id"));//"myDiv" console.log(div.getAttribute("class"));//"bd"
- 设置特性:setArribute()。接受两个参数:要设置的属性名和值。特性存在则修改,不存在则创建并设置值。
div.setArribute("id","someOtherId");
console.log(div.getArribute("id"));//"someOtherId"
- removeAttribute()。彻底删除元素的特性。
- attributes属性
- 包含NamedNodeMap。元素的每一个特性都由一个Attr节点表示,每个节点都保存在NamedNodeMap对象中。
- NamedNodeMap拥有的方法:
1).getNamedItem(name):返回nodeName属性等于name的节点
2).removeNamedItem(name):从列表中移除nodeName属性等于name的节点。
3).setNamedItem(node):向列表中添加节点,以节点的nodeName属性为索引。
4).item(pos):返回位于数字pos位置处的节点。
- 遍历元素时,attribute可以派上用场。使用数组保存名值对,再以空格为分隔符将他们拼接起来。
//迭代每一个元素特性,然后将它们构造成name = "value" name = "value"这样的格式字符串
function 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;
if(element.attributes[i].specified){
pairs.push(attrName+"=\""+attrValue +"\"");
}
}
return pairs.join(" ");
}
- 创建元素:createElement(),接受一个参数即要创建元素的标签
var div = document.createElement("div");
div.id = "myNewDiv";
div.className = "box";
//把新元素添加到文档树
document.body.appendChild(div);
- 元素的子节点
for(var i=0,len = element.childNodes.length; i<len,i++){
if(element.childNode[i].nodeType == 1){ //检查该元素是否是节点
//执行某些操作
}
}
通过特定标签名取得子节点或后代节点,使用getElementsByTagName()方法。
var ul = document.getElementByID("myList");//myList为ul的id值
var items = ul.getElementsByTagName("li");
Text类型
- 特征
- nodeType值为3;
- nodeName值为”#text”;
- nodeValue值为节点所包含的文本;
- parentNode是一个Element;
- 没有子节点
可以通过nodeValue属性或date属性访问Text节点中包含的文本。使用下列方法可以操作节点中的文本。
- appendDate(text):将text添加到节点末尾
- deleteDate(offset,count):从offset开始删除count个字符
- insertDate(offset,text):在offset指定位插入文本
- replaceDate(offset,count,text):用text替换从offset+count为止处的文本
- splitText(offset):从offset指定位置将文本分成两个文本节点
substringDate(offset,count):提取从指定位开始到offset+count为止处的字符串
<div>Hello World</div> var textNode = div.firstChild;//访问文本子节点 div.firstChild.nodeValue = "Some other message";//修改内容
创建文本节点:document.createTextNode(),接受参数为要插入节点中的文本
var element = document.createElement("div");//创建div element.className = "message"; var textNode = document.createTextNode("Hello world");//新建文本节点,添加到前面创建的元素中 element.appendChild(textNode); document.body.appendChild(element);//将元素添加到文档中
规范化文本节点:normalize()方法。在节点调用normalize()会将文本节点合并成一个节点
- 分割文本节点:splitText(offset):从offset指定位置将文本分成两个文本节点