一、节点层次
1.1、Node类型
一共有12种节点类型
除了IE外,所有的浏览器都可以访问到这个类型。js中所有的节点都继承自Node类型,因此所有的节点类型都共享着相同的基本属性和方法
1.1.1、nodeName和nodeValue属性
这两个属性完全取决与节点的类型,在使用这两个属性以前,最好是先检测以下节点的类型
if(someNode.nodeType==1){
value=someNode.nodeName;
}
如果是一个元素节点,则可以使用nodeName和nodeValue这两个属性,对于元素节点,nodeName中始终保存着元素的标签名,nodeValue的值始终为null
1.1.2、节点关系
每一个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点
访问保存在nodeList中的节点-可以通过方括号,也可以通过item()方法
var friendChild=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)//针对非ie浏览器
}catch(ex){
array=new Array()
for(var i=0,len=nodes.length;i<len;i++){
array.push(nodes[i])
}
}
return array
}
节点中,子节点,父节点,兄弟节点的关系
hasChildNodes():这个方法在节点包含一个或多个子节点的情况下放回true
所有节点的最后一个属性都是ownerDoucment,该属性指向表示整个文档的文本节点
1.1.3、操作节点
- appendChild(newNode):向列表末尾添加一个节点,返回值为插入的新节点
var returnedNode=someNode.appenChild(newNode);
console.log(returnedNode==newNode)
console.log(someNode.lastChild==newNode)
- insertBefore():这个方法接收两个参数,要插入的节点和作为参照的节点,返回值为插入的新节点
//插入成为最后一个节点
var returnedNode=someNode.insertBefore(newNode,null);
console.log(newNode=someNode.lastChild)
//插入成为第一个节点
returnedNode=someNode.insertBefore(newNode,someNode.firstNode);
console.log(returnedNode==newNode)
console.log(newNode==someNode.firstNode)
- replaceChild():要插入的节点和要替换的节点,返回值为被移除的节点
var returnedNode=someNode.replaceChild(newNode,someNode.firstChild)
- removeChild():要移除的节点,返回移除的节点
function myFunction()
{
var list=document.getElementById("myList");
list.removeChild(list.firstChild);
}
1.1.4、其他方法
- cloneNode():参数为一个布尔值,表示是否执行深复制,在参数为true时,执行深复制,也就是复制节点以及整个子树。
在参数为false时,执行浅复制,即只复制节点本身,复制后返回的节点副本属于文档所有,但是并没有为其指定父节点,因此,这个节点副本成为了一个“孤儿”
var list=document.getElementById("myList");
var deepList=list.cloneNode(true);
console.log(deepList.childNodes.length)//3
var shallowList=list.cloneNode(false);
onsole.log(shallowList.childNodes.length)//0
- normalize()处理文档树中的文本节点,如果找到了空白节点,则删除,如果找到了两个以上的文本节点,则合并
1.2、Document类型
document类型表示文档,其子节点可能是DocumentType,Element,ProcessInstruction或者Comment
1.2.1、文档的子节点
两个访问子节点的快捷方式
第一个是documentElement属性,该属性永远指向页面中的html元素
第二个是通过childNodes列表来访问文档元素
var html=document.documentElement;
console.log(html===document.childNodes[0]);//true
console.log(html===document.firstChild)//true
作为HTMLDocument的实例,document对象还有一个body属性,直接指向body属性
var body=docunment.body
1.2.2、文档信息
document.title
//取得标题
var originalTitle=document.title;
console.log(originalTitle)
//取得url
var url=document.URL;
//取得域名
var domain=document.domain;
//取得来源页面的URL
var referrer=document.referrer
console.log(url)//http://127.0.0.1:5500/document.html
console.log(domain)//127.0.0.1
console.log(referrer)//http://127.0.0.1:5500/document.html
如果URL中包含一个子域名,就只能将domain设置为URL中包含的域
//假设页面来自p2p.wrox.com域
document.domain="wrox.com"//成功
document="nczonline.net"//出错
当页面中包含来自其他子域的框架或者内嵌框架时,需要将每个页面的document.domain设置为相同的值
浏览器对domain还有一个限制。即如果域名一开始是松散的,那么不能将他在设为紧绷的。换句话说,在将domain设置为"wrox.com"后,不能再设置回"p2p.wrox.com"
//假设页面来自p2p.wrox.com域
document.domain="wrox.com"//成功
document="p2p.wrox.com"//出错
`
1.2.3、查找元素(都是以HTMLDocument为例)
- getElementById()
- getElementByTagName():返回的是包含零或多个元素的NodeList
- namedItem():通过元素的name特性取得集合中的项
var myImage=images.namedItem("myImage");
console.log(myImage)// <img src="myimages" name="myImage">
//或者
var myImage=images["myImage"]
console.log(myImage)//<img src="myimages" name="myImage">
- getElementByName():返回带有给定name的所有元素,也是一个NodeList
1.2.4、特殊集合
1.2.5、Dom一致性检测
hasFeature():接受两个参数,要检测的功能的名称及版本号
1.2.6文档写入
write():接受一个参数,要写入的文本
writeln()接受一个参数,要写入的文本,但是会在字符串末尾加一个\n
open()
close()
1.3、Element类型
element类型用于表现或者HTML元素,提供对元素标签名,子节点及特性的访问
其子节点可能是Element,Text,Comment,Processing Instruction,CDATASection挥着EntityReference
1.3.1、html元素
id,title,lang,dir,className
1.3.2、取得特性
getAttribute():
setAttribute():可以操作特性,也可以操作自定义属性
操作自定义属性时,方法二将获取不到自定义的属性
//方法一:
div.setAttribute("myColor","red")
console.log(div.getAttribute("myColor"))//red
//方法二:
div.myColor="red"
console.log(div.getAttribute("myColor"))//null
removeAttribute():
div[0].removeAttribute("id")
console.log(div[0].getAttribute("id"))//null
1.3.3、attribute属性
特性就是存在域attributes中的节点
遍历元素的特性
function outputAttributes(element){
var pairs=new Array(),
attrName,
attrValue
for(var i=0,len=element.attributed;i<len;i++){
attrName=element.attributes[i].nodeName
attrValue=element.attributes[i].nodeValue
if(element.attributes[i].specified){
pair.push(attrName+"=\""+attrValue+"\"")
}
}
return pairs.join('')
}
1.3.4、创建元素
document.createElement()
1.3.5、元素的子节点
元素的childNodes中包含了它所有的子节点
<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li></ul>
在IE浏览器中,ul会有三个子节点,其他浏览器中,会有七个元素,三个li,和四个文本节点(表示
- 元素之间的空格)
这就意味着,在需要通过childNodes属性遍历子节点的时候,要先执行 -
for(var i-0,len=element.childNodes.length;i<len;i++) if(element.childNodes[i].nodeType==1){ //执行某些操作 } }
1.4、Text类型
文本节点由Text类型表示,包含的是可以照字面量解释的纯文本内容
获取文本节点,在默认情况下,每个可以包含内容的元素最多只有一个文本节点var textNode=div.firstChild //或者 div.childNodes[0]
操作节点中的文本
appendData(text)
deleteData(offset,count)
insertData(offset,text)
replaceData(offset,count,text)
splitText(offset)var p=document.getElementsByTagName("p")[0]; p.childNodes[0].appendData("!")//Hello China! p.childNodes[0].deleteData(0,2)//llo China! p.childNodes[0].insertData(0,"I Love ");//I Love Hello China p.childNodes[0].replaceData(0,5,"I Love ")//I Love China var result=p.childNodes[0].splitText(5)//world
1.4.1、创建文本节点
document.createTextNode
console.log(element.childNodes.length);//2 element.normalize(); console.log(element.childNodes.length);//1 console.log(element.firstChild.nodeValue)//Hello WorldTippee
1.4.2、分割文本节点
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); console.log(element.firstChild.nodeValue);//hello console.log(newNode.nodeValue);//world console.log(element.childNodes.length)//2
1.4.3、Attr类型
在所有的浏览器中都可以访问到Attr类型的构造函数和原型,attr对象有三个属性:name,value,specified。
name是特性名称
value是特性的值
specified是一个布尔值,用以区别对待特性是在代码中指定的,还是默认的document.createAttribute():创建特性节点,且要将新创建的特性添加到元素中,必须使用元素的setAttributeNode()方法
var element=document.getElementById("div") var attr=document.createAttribute("align"); attr.value="left";element.setAttributeNode(attr); console.log(element.attributes["align"].value);//left console.log(element.getAttributeNode("align").value);//left console.log(element.getAttribute)//left
二、DOM操作技术
2.1、动态脚本
2.2、动态样式
2.3、操作表格
2.4、使用NodeList
NodeList,NamedNodeMap,HTMLCollection都是动态的,
每当文档结构发生变化时,NodeList会得到更新,因此他们总是保存着最新的信息
例如,下面的例子就会导致无限循环var divs=document.getElementsByTagName("div"), i, div console.log(divs) for(i=0;i<divs.length;i++){ div=document.createElement("div"); document.body.appendChild(div) }
要想迭代一个NodeList,最好使用length属性初始化第二个变量
var divs=document.getElementsByTagName("div"), i, div console.log(divs) for(i=0,len=divs.length;i<<len;i++){ div=document.createElement("div"); document.body.appendChild(div) }