- 浏览: 247546 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
seraph_fd:
已取用,谢谢。但将base64编码换成了Hex编码。
AES 加密 PHP 和 JAVA 互通 -
洋葱骑士:
调了一下OK了可是运行的时候,访问不了网站,出现域名错误
flexbuilder 和eclipse 整合 BlazeDs -
洋葱骑士:
出错了。。。。-无法将“<mx:RemoteObject ...
flexbuilder 和eclipse 整合 BlazeDs -
raxliao:
这个只支持16位的密钥,而且密码不能只能aes的随机码。不过测 ...
AES 加密 PHP 和 JAVA 互通 -
cnfnidt:
wwwwwwwwww
flex4 解析XML 例子
第六章 DOM基础
节点的层次
DOM定义了Node的接口以及许多种节点类型来表示XML节点的多个方面:
Document------最顶层的节点,所有的其他节点都是附属于它的。
DocumentType--DTD引用(使用<!DOCTYPE>语法)的对象表现形式,例如<!DOCTYPE HTML PUBLIC "-//w3c//DTD HTML 4.0 Transitional//EN">.它不能包含子节点。
DocumentFragment------可以像Document一样来保存其他节点
Element-------表示起始标签和结束标签之间的内容,例如<tag></tag>.这是唯一可以同时包含特性和子节点的节点类型。
Attr-------代表一对特性名和特性值。这个节点类型不能包含子节点。
Text-----代表XML文档中在起始标签和结束标签之间,或者CDate Section内包含的普通文本。这个节点类型不能包含子节点。
CDataSection--<![CDATA[]]>的对象表现形式。这个节点类型仅能包含文本节点Text作为子节点。
Entity----表示在DTD中的一个实体定义,例如<!ENTITY foo "foo">.这个节点类型不能包含子节点。
EntityReference----代表一个实体引用,例如"这个节点类型不能包含子节点。
ProcessingInstruction--代表一个PI.这个节点类型不能包含子节点。
Comment---代表XML注释。这个节点类型不能包含子节点。
Notation--代表在DTD中定义的记号。
---------------------------------------------------
Node接口定义了对应不同节点类型的12个常量:
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)
Node接口也定义了一些所有节点类型都包含的特性和方法。
-------------------------------------------------------------------------------------------
特性/方法 类型/返回类型 说明
-------------------------------------------------------------------------------------------
nodeName String 节点的名字;根据节点的类型而定义
nodeValue String 节点的值,根据节点的类型而定义。
nodeType Number 节点的类型常量值之一
ownerDocument Document 指向这个节点所属的文档
firstChild Node 指向在childNodes列表中的第一个节点
lastChild Node 指向在childNodes列表中的最后一个节点
childNodes NodeList 所有节点的列表
previousSibling Node 指向前一个兄弟节点,如果这个节点就是第一个兄弟节点,那么该值为null
nextSibling Node 指向后一个兄弟节点,如果这个节点就是最后一个兄弟节点,那么该值为null
hasChildNodes() Boolean 当childNodes包含一个或多个节点时,返回真
attributes NamedNodeMap 包含了代表一个元素的特性的Attr对象,仅用于Element节点
appendChild(node) Node 将node添加到childNodes的末尾
removeChild(node) Node 从childNodes中删除node
replaceChild(newnode,oldnode) Node 将childNodes中的oldnode替换成newnode
insertBefore(newnode,refnode) Node 在childNodes中的refnode之前插入newnode
-----------------------------------------------------------------------------------------------------------------------
NodeList-----节点数组,按照数值进行索引;用来表示一个元素的子节点。
NamedNodeMap----同时用数值和名字进行索引的节点表、用于表示元素特性。
注意:
普通HTML并不是合法的XML.然而,大部分当前的Web浏览器都很宽容,依然可以将一个HTML文档解析为合适的DOM文档(即使没有XML语言)。
但是,在编写Web页面的时候最好使用XHTML代码以消除哪些坏的编码习惯。
DOM操作示例:
<html>
<head>
<title></title>
</head>
<body>
<p>Hello World!</p>
<p>Isn't this excinting?</p>
<p>You're learning to use the DOM!</p>
</body>
</html>
<script>
var oHtml=document.documentElement;
var oHead=oHtml.firstChild;
var oBody=oHtml.lastChild;
//alert(oHtml.childNodes.length);
//alert(oHead.parentNode==oHtml);//outputs "true"
//alert(oBody.parentNode==oHtml);//outputs "true"
//alert(oBody.previousSibling==oHead);//outputs "true"
alert(document.nodeType);
alert(document.nodeType==Node.DOCUMENT_NODE);//outputs "true" IE下报错
</script>
IE的错误,可以通过定义匹配节点类型的常量来纠正这种情况。
if(typeof Node=="undefined"){
var Node={
ELEMENT_NODE:1,
ATTRIBUTE_NODE:2,
TEXT_NODE:3,
CDATA_SECTION_NODE:4,
ENTITY_REFERENCE_NODE:5,
ENTITY_NODE:6,
PROCESSING_INSTRUCTION_NODE:7,
COMMENT_NODE:8,
DOCUMENT_NODE:9,
DOCUMENT_TYPE_NODE:10,
DOCUMENT_FRAGMENT_NODE:11,
NOTATION_NODE:12
}
}
处理特性
正如前面提到的,即便Node接口已具有attributes方法,且已被所有类型的节点继承,然而,只有Element节点才能有特性。
Element节点的attributes属性其实是NamedNodeMap,它提供一些用于访问和处理其内容的方法:
getNamedItem(name)----返回nodeName属性值等于name的节点;
removeNamedItem(name)--删除nodeName属性值等于name的节点;
setNamedItem(node)---将node添加到列表中,按其nodeName属性进行索引。
item(pos)--------像NodeList一样,返回在位置pos的节点.
注意:
请记住这些方法都是返回一个Attr节点,而非特性值。
例:
<p style="color:red;" id="pl">Hello world</p>
<script>
var oP=document.getElementById("pl");
var sId=oP.attributes.getNamedItem("id").nodeValue;
//var sId2=oP.attributes.item(1).nodeValue;
alert(sId);// outputs "pl"
//alert(sId2);
oP.attributes.getNamedItem("id").nodeValue="newId";
</script>
DOM新定义了三个操作元素方法来帮助访问特性:
getAttribute(name)----等于attributes.getNamedItem("id").value;
setAttribute(name,newvalue)--等于attributes.getNamedItem(name).value=newvalue;
removeAttribute(name)------等于attributes.removeNamedItem(name);
例:
<p style="color:red;" id="pl">Hello world</p>
<script>
var oP=document.getElementById("pl");
var sId=oP.getAttribute("id");
alert(sId);// outputs "pl"
</script>
访问指定节点
1.getElementsByTagName()
核心(XML)DOM定义了getElementsByTagName()方法,用来返回一个包含所有tagName(标签名)特性等于某个指定值
的元素的NodeList.在Element对象中,tagName特性总是等于小于号之后紧随的名称--例如,<img/>的tagName是"img".
例:
var oImags=document.getElementsByTagName("img");
alert(oImags[0].tagName);//outputs "IMG"
假如你只想获取在某个页面第一个段落的所有图像?可以通过对第一个段落元素调用getElementsByTagName()来完成.
var oPs=document.getElementsByTagName("p");
var oImgsInp=oPs[0].getElementsByTagName("img");
可以使用一个星号的方法来获取document中的所有元素
var oAllElements=document.getElementsByTagName("*");
注意:
当参数是一个星号的时候,IE6.0并不返回所有的元素。必须使用document.all来替代它。
2.getElementsByName()
HTML DOM定义了getElementsByName(),它用来获取所有name特性等于指定值的元素的。
例:
<input type="radio" name="radColor" value="red"/>Red<br/>
<input type="radio" name="radColor" value="green"/>green<br/>
<input type="radio" name="radColor" value="blue"/>blue<br/>
<script>
var oRadios=document.getElementsByName("radColor");
alert(oRadios.length+"--"+oRadios[0].getAttribute("value"));
</script>
注意:
IE6.0和Opear7.5在这个方法的使用上还存在一些错误。首先,它们还会id等于给定名称的元素。
第二,它们仅仅检查<input/>和<img/>元素.
3.getElementById()
这是HTML DOM定义的第二种方法,它将返回id特性等于指定值的元素。在HTML中,id特性是唯一的--
这意味着没有两个元素可以共享同一id.毫无疑问这是从文档树中获取单个指定元素最快的方法。
例:
<div id="div1">This is my first layer</div>
<script>
var oDivs=document.getElementsByTagName("div");
var oDiv1=null;
for(var i=0;i<oDivs.length;i++){
if(oDivs[i].getAttribute("id")=="div1"){
oDiv1=oDivs[i];
alert(oDiv1.innerHTML);
break;
}
}
var oDiv1=document.getElementById("div1");
</script>
注意:
如果给定的ID匹配某个元素的name特性,IE6.0还会返回这个元素。这是一个bug,也是你必须非常小心的一个问题。
创建和操作节点
1.创建新节点
DOM Document(文档)中有一些用于创建不同类型的节点,即便在所有的浏览器中的浏览器documetn对象并不需要
全部支持所有的方法。
---------------------------------------------------------------------------------------
方法 描述 IE MOZ OP SAF
----------------------------------------------------------------------------------------
createAttribute(name) 用给定名称name创建特性节点 X X X -
createCDATASection 用饱含文本text的文本子节点 - X - -
创建一个CADATASection
createComment(text) 创建包含文本text的注释节点 X X X X
createDocumentFragement()创建文档碎片节点 X X X X
createElement(tagname) 创建给定名称的实体引用节点 - X - -
createProcessing 创建包含给定名称的实体引用
Instruction(target,data) 节点 - X - -
createTextNode(text) 创建包含文本text的文本节点 X X X X
----------------------------------------------------------------------------------------
最常用用到的几个方法是:createDocumentFragment(),createElement()和createTextNode();其他的一些
方法要么就是没什么用(createComment()),要么就是浏览器的支持不够,目前还不太能用。
2.createElement(),createTextNode(),appendChild()
例:
使用DOM来添加下列代码到页面中:
<p>Hello World!</p>
<script>
var oP=document.createElement("p");
var oText=document.createTextNode("Hello World!");
oP.appendChild(oText);
document.body.appendChild(oP);
</script>
注意:
在这里,我必须谨慎地告诉你所有的DOM操作必须在页面完全载入之后才能进行。当页面正在载入时,要向DOM
插入相关代码是不可能的,因为页面完全下载到客户端机器之前,是无法完全构建DOM数的。因为这个原因,必须使用onload
时间句柄来执行所有代码。
3.removeChild(),replaceChild()和insertBefore()
<html>
<head>
<title>removeChild() Example</title>
<script>
function removeMessage(){
var oP=document.body.getElementsByTagName("p")[0];
//document.body.removeChild(oP);
/*******最好使用节点的parentNode特性来确保每次你都能访问到它真正的父节点**************/
oP.parentNode.removeChild(oP);
}
</script>
</head>
<body onload="removeMessage()">
<p>Hello World</p>
</body>
</html>
假如想将这个消息替换成新的内容,则使用replaceChild()方法.
replaceChild()方法有两个参数:被添加的节点和被替换的节点。这样,可以创建一个包含新消息的元素,并用它替换原来包含
"Hello World!"消息的<p/>元素.
<html>
<head>
<title>replaceChild() Example</title>
<script>
function replaceMessage(){
var oNewP=document.createElement("p");
var oText=document.createTextNode("Hello Universe!");
oNewP.appendChild(oText);
var oOldP=document.body.getElementsByTagName("p")[0];
oOldP.parentNode.replaceChild(oNewP,oPldP);
}
</script>
</head>
<body onload="replaceMessage()">
<p>Hello World</p>
</body>
</html>
appendChild()
<script>
var oNewP=document.createElement("p");
var oText=document.createTextNode("Hello Universe!");
oNewP.appendChild(oText);
document.body.appendChild(oNewP);
</script>
insertBefore()方法接收两个参数:要添加的节点和插在那个节点之前.
<html>
<head>
<title>insertBefore() Example</title>
<script>
function insertMessage(){
var oNewP=document.createElement("p");
var oText=document.createTextNode("Hello Universe!");
oNewP.appendChild(oText);
var oOldP=document.body.getElementsByTagName("p")[0];
document.body.insertBefore(oNewP,oOldP);
}
</script>
</head>
<body onload="insertMessage()">
<p>Hello World</p>
</body>
</html>
4.createDocumentFragment()
一旦把节点添加到document.body(或者它的后代节点)中,页面就会更新并反映出这个变化。对于少量的更新,
这个很好的,就像在前面的列子中那样。然而,当要向document添加大量数据时,如果逐个添加这些变动,这
个过程可能会十分缓慢。为解决这个问题,可以创建一个文档碎片,把所有的新节点附加其上,然后把文档碎片
的内容一次性添加到document中。
假设你想创建十个新段落。若使用前面学到的方法,可能会写出这种代码:
var arrText=["first","second","third","fourth","fifth","sixth"];
for(var i=0;i<arrText.length;i++){
var oP=document.createElement("p");
var oText=document.createTextNode(arrText[i]);
oP.appendChild(oText);
document.body.appendChild(oP);
}
这段代码运行良好,但问题是它调用了十次document.body.appendChild(),每次都要产生一次页面刷新。
这是,文档碎片就十分有用:
var arrText=["first","second","third","fourth","fifth","sixth"];
var oFragment=document.createDocumentFragment();
for(var i=0;i<arrText.length;i++){
var oP=document.createElement("p");
var oText=document.createTextNode(arrText[i]);
oP.appendChild(oText);
oFragment.appendChild(oP);
}
document.body.appendChild(oFragment);
在这段代码中,每个新的<p/>元素都被添加到文档碎片中。然后,这个碎片被作为参数传递给appendChild().
这里对appendChild()的调用实际上并不是把文档碎片节点本身追加到<body/>元素中,而是仅仅追加碎片中的子节点。
然后,可以看到很明显的性能提升。调用document.body.appendChild()一次来替代十次,这意味着只需要进行一次
屏幕刷新。
HTML DOM特征功能
核心DOM的特性和方法是通用的,是为了在各种情况下操作所有XML文档而设计的.
HTML DOM的特性和方法是在专门针对HTML的同时也让一些DOM操作更加简便.这包括将特性
作为属性进行访问的能力,以及特定于元素的属性和方法。
例:
<img src="mypicture.jpg" border="0"/>
<script>
/*******使用核心的DOM*********/
alert(oImg.getAttribute("src"));
alert(oImg.getAttribute("border"));
oImg.setAttribute("src","mypicture2.jpg");
oImg.setAttribute("border","1");
/********使用HTML DOM**************/
alert(oImg.src);
alert(oImg.border);
oImg.src="mypicture2.jpg"
oImg.border="1";
</script>
唯一的特性名和属性名不一样的特例是class特性,它是用来指定应用于某个元素的一个CSS类.
因为class在ECMAScript中是一个保留字,在JavaScript中,它不能被作为变量名、属性名或
函数名。于是,相应的属性名就变成className:
alert(oDiv.className);
oDiv.className="footer";
通过使用属性来访问特性的方式来替代getAttribute()和setAttribute()并无实质性的益处,除了可能缩减代码的
长度以及令代码变得易读。
注意:
IE在setAttribute()上有个很大的问题:当你使用它事,变更并不会总是正确地反应出来。
如果你打算支持IE,最好尽可能使用属性。
table方法:
假设想使用DOM来创建如下的HTML表格:
<table border="1" width="100%">
<tbody>
<tr>
<td>Cell 1,1</td>
<td>Cell 2,1</td>
</tr>
<tr>
<td>Cell 1,1</td>
<td>Cell 2,1</td>
</tr>
</tbody>
</table>
<script>
var oTable=document.createElement("table");
oTable.setAttribute("border","1");
oTable.setAttribute("width","100%");
var oTBody=document.createElement("tbody");
oTable.appendChild(oTBody);
var oTR1=document.createElement("tr");
oTBody.appendChild(oTR1);
var oTD11=document.createElement("td");
oTD11.appendChild(document.createTextNode("Cell 1,1"));
oTR1.appendChild(oTD11);
var oTD21=document.createElement("td");
oTD21.appendChild(document.createTextNode("Cell 2,1"));
oTR1.appendChild(oTD21);
var oTR2=document.createElement("tr");
oTBody.appendChild(oTR2);
var oTD12=document.createElement("td");
oTD12.appendChild(document.createTextNode("Cell 1,2"));
oTR2.appendChild(oTD12);
var oTD22=document.createElement("td");
oTD22.appendChild(document.createTextNode("Cell 2,2"));
oTR2.appendChild(oTD22);
document.body.appendChild(oTable);
</script>
这段代码十分的冗长而且有些难于理解。为了协助建立表格,HTML DOM给<table/>,<tbody/>和<tr/>等
元素添加了一些特性和方法.
给<table/>元素添加了一下内容:
caption--指向<caption/>元素
tBodies---<tbody/>元素的集合
tFoot--指向<tfoot/>元素(如果存在)
tHead--指向<thead/>元素(如果存在)
rows---表格中所有行的集合
createThead()--创建<thead/>元素并将其放入表格
createTFoot()--创建<tfoot/>元素并将其放入表格
createCaption()--创建<caption/>元素并将其放入表格
deleteTHead()--删除<thead/>元素
deleteTFoot()--删除<tfoot/>元素
deleteCaption()--删除<caption/>元素
deleteRow(position)--删除<caption/>元素
insertRow(position)--在rows集合中的指定位置插入一个新行
<tbody/>元素添加了一下内容:
rows---<tbody/>中的所有行的集合
deleteRow(position)--删除指定位置上的行
insertRow(position)--在rows集合中的指定位置插入一个新行
<tr/>元素中添加了一下内容
cells--<tr/>元素中所有的单元格的集合
deleteCell(position)--删除给定位置上的单元格
insertCell(position)--在cells集合的给定位置上插入一个新的单元格
上面的一切意味着什么?简单地说,它意味着如果使用这些简单的属性和方法就可以大大降低
创建表格的复杂度。
例:
<script>
var oTable=document.createElement("table");
oTable.setAttribute("border","1");
oTable.setAttribute("width","100%");
var oTBody=document.createElement("tbody");
oTable.appendChild(oTBody);
oTBody.insertRow(0);
oTBody.rows[0].insertCell(0);
oTBody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1,1"));
oTBody.rows[0].insertCell(1);
oTBody.rows[0].cells[1].appendChild(document.createTextNode("Cell 2,1"));
oTBody.insertRow(1);
oTBody.rows[1].insertCell(0);
oTBody.rows[1].cells[0].appendChild(document.createTextNode("Cell 2,1"));
oTBody.rows[1].insertCell(1);
oTBody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2,2"));
document.body.appendChild(oTable);
</script>
遍历DOM
到目前为止,我们讨论的功能都仅仅是DOM Level 1的部分。本节将介绍一些DOM Level 2 的功能,
尤其是和遍历DOM文档相关的DOM Level 2遍历(traversal)和范围(range)规范中的对象。这些功能只有在Mozilla
和Kongueror/Safari中才有.
NodeIterator
第一有关的对象是NodeIterator,用它可以对DOM树进行深度优先的搜索。
要创建NodeIterator对象,请使用document对象的createNodeIterator()方法.这个方法接受四个参数:
1.root-----从树中开始搜索的那个节点。
2.whatToShow----一个数值代码,代表哪些节点需要访问
3.filter-------NodeFilter对象,用来决定需要忽略哪些节点
4.entityReferenceExpansion--布尔值,表示是否需要扩展实体引用。
通过应用下列一个或多个常量,whatToShow参数可以决定哪些节点可以访问.
NodeFilter.SHOW_ALL-------显示所有的节点类型
NodeFilter.SHOW_ELEMENT---显示元素节点
NodeFilter.SHOW_ATTRIBUTE---显示特性节点
NodeFilter.SHOW_TEXT------显示文本节点
NodeFilter.SHOW_CDATA_SECTION--显示CData section节点
NodeFilter.SHOW_ENTITY_REFERENCE--显示实体引用节点
NodeFilter.SHOW_ENTITY---显示实体节点
NodeFilter.SHOW_PROCESSING_INSTRUCTION--显示PI节点
NodeFilter.SHOW_COMMENT--显示注释节点
NodeFilter.SHOW_DOCUMENT--显示文档节点
NdeeFilter.SHOW_DOCUMENT_TYPE--显示文档类型节点
NodeFilter.SHOW_DOCUMENT_FRAGMENT--显示文档碎片节点
NodeFilter.SHOW_NOTATION---显示记号节点
可以通过使用二进制或操作符来组合多个值:
var iWhatToShow=NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT;
createNodeIterator()的filter(过滤器)参数可以指定一个自定义的NodeFilter对象,
但是如果不想使用它的话,也可以留空(null).
例:
创建访问所有节点类型的NodeIterator对象
var iterator=document.createNodeIterator(document,NodeFilter.SHOW_ALL,null,false);
要在搜索过程中前进或后退,可以使用nextNode()和previousNode()方法:
var node1=iterator.nextNode();
var node2=iterator.nextNode();
var node3=iterator.previousNode();
alert(node1==node3);//ouputs "true"
<html>
<head><title>NodeIterator Example</title>
<script type="text/javascript">
var iterator=null;
function makeList(){
var oDiv=document.getElementById("div1");
iterator=document.createNodeIterator(oDiv,NodeFilter.SHOW_ELEMENT,null,false);
var oOutput=document.getElementById("text1");
var oNode=iterator.nextNode();
while(oNode){
oOutput.value+=oNode.tagName+"\n";
oNode=iterator.nextNode();
}
}
</script>
</head>
<body>
<div id="div1">
<p>Hello <b>World!</b></p>
<ul>
<li>list item1</li>
<li>list item2</li>
<li>list item3</li>
</ul>
</div>
<textarea rows="10" cols="40" id="text1"></textarea><br/>
<input type="button" value="Make List" onclick="makeList()"/>
</body>
</html>
结果:DIV P B UL LI LI LI
但假设不想在结果中包含<p/>元素。这就不能仅使用whatToShow参数来完成。这种情况下,你
需要自定义一个NodeFilter对象。
NodeFilter对象只有一个方法:acceptNode().如果应该访问给定的节点,那么该方法返回NodeFilter.FILTER_ACCEPT;
如果不应该访问给定节点,则返回NodeFilter.FILTER_REJECT.然而,不能使用NodeFilter类来创建这个对象,因为这个类
是一个抽象类。
现在,只要创建任意一个有acceptNode()方法的对象,就可以将它传给createNodeIterator()方法。
var oFilter=new Object;
oFilter.acceptNode=function(oNode){
//filter logic goes here
//禁止p
return (oNode.tagName=="p")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT
};
<html>
<head><title>NodeIterator Example</title>
<script type="text/javascript">
var iterator=null;
function makeList(){
var oDiv=document.getElementById("div1");
var oFilter=new Object;
oFilter.acceptNode=function(oNode){
//filter logic goes here
//禁止p
return (oNode.tagName=="P")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT
};
iterator=document.createNodeIterator(oDiv,NodeFilter.SHOW_ELEMENT,oFilter,false);
var oOutput=document.getElementById("text1");
var oNode=iterator.nextNode();
while(oNode){
oOutput.value+=oNode.tagName+"\n";
oNode=iterator.nextNode();
}
}
</script>
</head>
<body>
<div id="div1">
<p>Hello <b>World!</b></p>
<ul>
<li>list item1</li>
<li>list item2</li>
<li>list item3</li>
</ul>
</div>
<textarea rows="10" cols="40" id="text1"></textarea><br/>
<input type="button" value="Make List" onclick="makeList()"/>
</body>
</html>
结果:DIV B UL LI LI LI
NodeIterator对象展示了一种有序的自顶向下遍历整个DOM树的方式。然而可能想遍历到树的
特定区域时,再看看莫个节点的兄弟节点或者子节点。如果是这种情况,可以使用TreeWalker.
TreeWalker
TreeWalker有点像NodeIterator的大哥:它有NodeIterator所有的功能(nextNode()和previousNode()),
并且添加了一些遍历方法:
parentNode()------进入当前节点的父节点
firstChild()------进入当前节点的第一个子节点
lastChild()-----进入当前节点的最后一个子节点
nextSibling()---进入当前节点的下一个兄弟节点
prevousSibling()---进入当前的前一个兄弟节点
要开始使用TreeWalker,其实完全可以像使用NodeIterator那样,只要把createNodeIterator()的调用改为调用
createTreeWalker(),这个函数接受同样的参数。
例:测试失败
<html>
<head><title>TreeWalker Example</title>
<script type="text/javascript">
var walker=null;
function makeList(){
var oDiv=document.getElementById("div1");
var oFilter=new Object;
oFilter.acceptNode=function(oNode){
//filter logic goes here
//禁止p
return (oNode.tagName=="P")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT
};
walker=document.createNodeIterator(oDiv,NodeFilter.SHOW_ELEMENT,oFilter,false);
var oOutput=document.getElementById("text1");
walker.firstChild();//go to <p>
walker.nextSibling();// to to <ul>
var oNode=walker.firstChild();
while(oNode){
oOutput.value+=oNode.tagName+"\n";
oNode=walker.nextNode();
}
}
</script>
</head>
<body>
<div id="div1">
<p>Hello <b>World!</b></p>
<ul>
<li>list item1</li>
<li>list item2</li>
<li>list item3</li>
</ul>
</div>
<textarea rows="10" cols="40" id="text1"></textarea><br/>
<input type="button" value="Make List" onclick="makeList()"/>
</body>
</html>
//outputs "LI LI LI"
节点的层次
DOM定义了Node的接口以及许多种节点类型来表示XML节点的多个方面:
Document------最顶层的节点,所有的其他节点都是附属于它的。
DocumentType--DTD引用(使用<!DOCTYPE>语法)的对象表现形式,例如<!DOCTYPE HTML PUBLIC "-//w3c//DTD HTML 4.0 Transitional//EN">.它不能包含子节点。
DocumentFragment------可以像Document一样来保存其他节点
Element-------表示起始标签和结束标签之间的内容,例如<tag></tag>.这是唯一可以同时包含特性和子节点的节点类型。
Attr-------代表一对特性名和特性值。这个节点类型不能包含子节点。
Text-----代表XML文档中在起始标签和结束标签之间,或者CDate Section内包含的普通文本。这个节点类型不能包含子节点。
CDataSection--<![CDATA[]]>的对象表现形式。这个节点类型仅能包含文本节点Text作为子节点。
Entity----表示在DTD中的一个实体定义,例如<!ENTITY foo "foo">.这个节点类型不能包含子节点。
EntityReference----代表一个实体引用,例如"这个节点类型不能包含子节点。
ProcessingInstruction--代表一个PI.这个节点类型不能包含子节点。
Comment---代表XML注释。这个节点类型不能包含子节点。
Notation--代表在DTD中定义的记号。
---------------------------------------------------
Node接口定义了对应不同节点类型的12个常量:
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)
Node接口也定义了一些所有节点类型都包含的特性和方法。
-------------------------------------------------------------------------------------------
特性/方法 类型/返回类型 说明
-------------------------------------------------------------------------------------------
nodeName String 节点的名字;根据节点的类型而定义
nodeValue String 节点的值,根据节点的类型而定义。
nodeType Number 节点的类型常量值之一
ownerDocument Document 指向这个节点所属的文档
firstChild Node 指向在childNodes列表中的第一个节点
lastChild Node 指向在childNodes列表中的最后一个节点
childNodes NodeList 所有节点的列表
previousSibling Node 指向前一个兄弟节点,如果这个节点就是第一个兄弟节点,那么该值为null
nextSibling Node 指向后一个兄弟节点,如果这个节点就是最后一个兄弟节点,那么该值为null
hasChildNodes() Boolean 当childNodes包含一个或多个节点时,返回真
attributes NamedNodeMap 包含了代表一个元素的特性的Attr对象,仅用于Element节点
appendChild(node) Node 将node添加到childNodes的末尾
removeChild(node) Node 从childNodes中删除node
replaceChild(newnode,oldnode) Node 将childNodes中的oldnode替换成newnode
insertBefore(newnode,refnode) Node 在childNodes中的refnode之前插入newnode
-----------------------------------------------------------------------------------------------------------------------
NodeList-----节点数组,按照数值进行索引;用来表示一个元素的子节点。
NamedNodeMap----同时用数值和名字进行索引的节点表、用于表示元素特性。
注意:
普通HTML并不是合法的XML.然而,大部分当前的Web浏览器都很宽容,依然可以将一个HTML文档解析为合适的DOM文档(即使没有XML语言)。
但是,在编写Web页面的时候最好使用XHTML代码以消除哪些坏的编码习惯。
DOM操作示例:
<html>
<head>
<title></title>
</head>
<body>
<p>Hello World!</p>
<p>Isn't this excinting?</p>
<p>You're learning to use the DOM!</p>
</body>
</html>
<script>
var oHtml=document.documentElement;
var oHead=oHtml.firstChild;
var oBody=oHtml.lastChild;
//alert(oHtml.childNodes.length);
//alert(oHead.parentNode==oHtml);//outputs "true"
//alert(oBody.parentNode==oHtml);//outputs "true"
//alert(oBody.previousSibling==oHead);//outputs "true"
alert(document.nodeType);
alert(document.nodeType==Node.DOCUMENT_NODE);//outputs "true" IE下报错
</script>
IE的错误,可以通过定义匹配节点类型的常量来纠正这种情况。
if(typeof Node=="undefined"){
var Node={
ELEMENT_NODE:1,
ATTRIBUTE_NODE:2,
TEXT_NODE:3,
CDATA_SECTION_NODE:4,
ENTITY_REFERENCE_NODE:5,
ENTITY_NODE:6,
PROCESSING_INSTRUCTION_NODE:7,
COMMENT_NODE:8,
DOCUMENT_NODE:9,
DOCUMENT_TYPE_NODE:10,
DOCUMENT_FRAGMENT_NODE:11,
NOTATION_NODE:12
}
}
处理特性
正如前面提到的,即便Node接口已具有attributes方法,且已被所有类型的节点继承,然而,只有Element节点才能有特性。
Element节点的attributes属性其实是NamedNodeMap,它提供一些用于访问和处理其内容的方法:
getNamedItem(name)----返回nodeName属性值等于name的节点;
removeNamedItem(name)--删除nodeName属性值等于name的节点;
setNamedItem(node)---将node添加到列表中,按其nodeName属性进行索引。
item(pos)--------像NodeList一样,返回在位置pos的节点.
注意:
请记住这些方法都是返回一个Attr节点,而非特性值。
例:
<p style="color:red;" id="pl">Hello world</p>
<script>
var oP=document.getElementById("pl");
var sId=oP.attributes.getNamedItem("id").nodeValue;
//var sId2=oP.attributes.item(1).nodeValue;
alert(sId);// outputs "pl"
//alert(sId2);
oP.attributes.getNamedItem("id").nodeValue="newId";
</script>
DOM新定义了三个操作元素方法来帮助访问特性:
getAttribute(name)----等于attributes.getNamedItem("id").value;
setAttribute(name,newvalue)--等于attributes.getNamedItem(name).value=newvalue;
removeAttribute(name)------等于attributes.removeNamedItem(name);
例:
<p style="color:red;" id="pl">Hello world</p>
<script>
var oP=document.getElementById("pl");
var sId=oP.getAttribute("id");
alert(sId);// outputs "pl"
</script>
访问指定节点
1.getElementsByTagName()
核心(XML)DOM定义了getElementsByTagName()方法,用来返回一个包含所有tagName(标签名)特性等于某个指定值
的元素的NodeList.在Element对象中,tagName特性总是等于小于号之后紧随的名称--例如,<img/>的tagName是"img".
例:
var oImags=document.getElementsByTagName("img");
alert(oImags[0].tagName);//outputs "IMG"
假如你只想获取在某个页面第一个段落的所有图像?可以通过对第一个段落元素调用getElementsByTagName()来完成.
var oPs=document.getElementsByTagName("p");
var oImgsInp=oPs[0].getElementsByTagName("img");
可以使用一个星号的方法来获取document中的所有元素
var oAllElements=document.getElementsByTagName("*");
注意:
当参数是一个星号的时候,IE6.0并不返回所有的元素。必须使用document.all来替代它。
2.getElementsByName()
HTML DOM定义了getElementsByName(),它用来获取所有name特性等于指定值的元素的。
例:
<input type="radio" name="radColor" value="red"/>Red<br/>
<input type="radio" name="radColor" value="green"/>green<br/>
<input type="radio" name="radColor" value="blue"/>blue<br/>
<script>
var oRadios=document.getElementsByName("radColor");
alert(oRadios.length+"--"+oRadios[0].getAttribute("value"));
</script>
注意:
IE6.0和Opear7.5在这个方法的使用上还存在一些错误。首先,它们还会id等于给定名称的元素。
第二,它们仅仅检查<input/>和<img/>元素.
3.getElementById()
这是HTML DOM定义的第二种方法,它将返回id特性等于指定值的元素。在HTML中,id特性是唯一的--
这意味着没有两个元素可以共享同一id.毫无疑问这是从文档树中获取单个指定元素最快的方法。
例:
<div id="div1">This is my first layer</div>
<script>
var oDivs=document.getElementsByTagName("div");
var oDiv1=null;
for(var i=0;i<oDivs.length;i++){
if(oDivs[i].getAttribute("id")=="div1"){
oDiv1=oDivs[i];
alert(oDiv1.innerHTML);
break;
}
}
var oDiv1=document.getElementById("div1");
</script>
注意:
如果给定的ID匹配某个元素的name特性,IE6.0还会返回这个元素。这是一个bug,也是你必须非常小心的一个问题。
创建和操作节点
1.创建新节点
DOM Document(文档)中有一些用于创建不同类型的节点,即便在所有的浏览器中的浏览器documetn对象并不需要
全部支持所有的方法。
---------------------------------------------------------------------------------------
方法 描述 IE MOZ OP SAF
----------------------------------------------------------------------------------------
createAttribute(name) 用给定名称name创建特性节点 X X X -
createCDATASection 用饱含文本text的文本子节点 - X - -
创建一个CADATASection
createComment(text) 创建包含文本text的注释节点 X X X X
createDocumentFragement()创建文档碎片节点 X X X X
createElement(tagname) 创建给定名称的实体引用节点 - X - -
createProcessing 创建包含给定名称的实体引用
Instruction(target,data) 节点 - X - -
createTextNode(text) 创建包含文本text的文本节点 X X X X
----------------------------------------------------------------------------------------
最常用用到的几个方法是:createDocumentFragment(),createElement()和createTextNode();其他的一些
方法要么就是没什么用(createComment()),要么就是浏览器的支持不够,目前还不太能用。
2.createElement(),createTextNode(),appendChild()
例:
使用DOM来添加下列代码到页面中:
<p>Hello World!</p>
<script>
var oP=document.createElement("p");
var oText=document.createTextNode("Hello World!");
oP.appendChild(oText);
document.body.appendChild(oP);
</script>
注意:
在这里,我必须谨慎地告诉你所有的DOM操作必须在页面完全载入之后才能进行。当页面正在载入时,要向DOM
插入相关代码是不可能的,因为页面完全下载到客户端机器之前,是无法完全构建DOM数的。因为这个原因,必须使用onload
时间句柄来执行所有代码。
3.removeChild(),replaceChild()和insertBefore()
<html>
<head>
<title>removeChild() Example</title>
<script>
function removeMessage(){
var oP=document.body.getElementsByTagName("p")[0];
//document.body.removeChild(oP);
/*******最好使用节点的parentNode特性来确保每次你都能访问到它真正的父节点**************/
oP.parentNode.removeChild(oP);
}
</script>
</head>
<body onload="removeMessage()">
<p>Hello World</p>
</body>
</html>
假如想将这个消息替换成新的内容,则使用replaceChild()方法.
replaceChild()方法有两个参数:被添加的节点和被替换的节点。这样,可以创建一个包含新消息的元素,并用它替换原来包含
"Hello World!"消息的<p/>元素.
<html>
<head>
<title>replaceChild() Example</title>
<script>
function replaceMessage(){
var oNewP=document.createElement("p");
var oText=document.createTextNode("Hello Universe!");
oNewP.appendChild(oText);
var oOldP=document.body.getElementsByTagName("p")[0];
oOldP.parentNode.replaceChild(oNewP,oPldP);
}
</script>
</head>
<body onload="replaceMessage()">
<p>Hello World</p>
</body>
</html>
appendChild()
<script>
var oNewP=document.createElement("p");
var oText=document.createTextNode("Hello Universe!");
oNewP.appendChild(oText);
document.body.appendChild(oNewP);
</script>
insertBefore()方法接收两个参数:要添加的节点和插在那个节点之前.
<html>
<head>
<title>insertBefore() Example</title>
<script>
function insertMessage(){
var oNewP=document.createElement("p");
var oText=document.createTextNode("Hello Universe!");
oNewP.appendChild(oText);
var oOldP=document.body.getElementsByTagName("p")[0];
document.body.insertBefore(oNewP,oOldP);
}
</script>
</head>
<body onload="insertMessage()">
<p>Hello World</p>
</body>
</html>
4.createDocumentFragment()
一旦把节点添加到document.body(或者它的后代节点)中,页面就会更新并反映出这个变化。对于少量的更新,
这个很好的,就像在前面的列子中那样。然而,当要向document添加大量数据时,如果逐个添加这些变动,这
个过程可能会十分缓慢。为解决这个问题,可以创建一个文档碎片,把所有的新节点附加其上,然后把文档碎片
的内容一次性添加到document中。
假设你想创建十个新段落。若使用前面学到的方法,可能会写出这种代码:
var arrText=["first","second","third","fourth","fifth","sixth"];
for(var i=0;i<arrText.length;i++){
var oP=document.createElement("p");
var oText=document.createTextNode(arrText[i]);
oP.appendChild(oText);
document.body.appendChild(oP);
}
这段代码运行良好,但问题是它调用了十次document.body.appendChild(),每次都要产生一次页面刷新。
这是,文档碎片就十分有用:
var arrText=["first","second","third","fourth","fifth","sixth"];
var oFragment=document.createDocumentFragment();
for(var i=0;i<arrText.length;i++){
var oP=document.createElement("p");
var oText=document.createTextNode(arrText[i]);
oP.appendChild(oText);
oFragment.appendChild(oP);
}
document.body.appendChild(oFragment);
在这段代码中,每个新的<p/>元素都被添加到文档碎片中。然后,这个碎片被作为参数传递给appendChild().
这里对appendChild()的调用实际上并不是把文档碎片节点本身追加到<body/>元素中,而是仅仅追加碎片中的子节点。
然后,可以看到很明显的性能提升。调用document.body.appendChild()一次来替代十次,这意味着只需要进行一次
屏幕刷新。
HTML DOM特征功能
核心DOM的特性和方法是通用的,是为了在各种情况下操作所有XML文档而设计的.
HTML DOM的特性和方法是在专门针对HTML的同时也让一些DOM操作更加简便.这包括将特性
作为属性进行访问的能力,以及特定于元素的属性和方法。
例:
<img src="mypicture.jpg" border="0"/>
<script>
/*******使用核心的DOM*********/
alert(oImg.getAttribute("src"));
alert(oImg.getAttribute("border"));
oImg.setAttribute("src","mypicture2.jpg");
oImg.setAttribute("border","1");
/********使用HTML DOM**************/
alert(oImg.src);
alert(oImg.border);
oImg.src="mypicture2.jpg"
oImg.border="1";
</script>
唯一的特性名和属性名不一样的特例是class特性,它是用来指定应用于某个元素的一个CSS类.
因为class在ECMAScript中是一个保留字,在JavaScript中,它不能被作为变量名、属性名或
函数名。于是,相应的属性名就变成className:
alert(oDiv.className);
oDiv.className="footer";
通过使用属性来访问特性的方式来替代getAttribute()和setAttribute()并无实质性的益处,除了可能缩减代码的
长度以及令代码变得易读。
注意:
IE在setAttribute()上有个很大的问题:当你使用它事,变更并不会总是正确地反应出来。
如果你打算支持IE,最好尽可能使用属性。
table方法:
假设想使用DOM来创建如下的HTML表格:
<table border="1" width="100%">
<tbody>
<tr>
<td>Cell 1,1</td>
<td>Cell 2,1</td>
</tr>
<tr>
<td>Cell 1,1</td>
<td>Cell 2,1</td>
</tr>
</tbody>
</table>
<script>
var oTable=document.createElement("table");
oTable.setAttribute("border","1");
oTable.setAttribute("width","100%");
var oTBody=document.createElement("tbody");
oTable.appendChild(oTBody);
var oTR1=document.createElement("tr");
oTBody.appendChild(oTR1);
var oTD11=document.createElement("td");
oTD11.appendChild(document.createTextNode("Cell 1,1"));
oTR1.appendChild(oTD11);
var oTD21=document.createElement("td");
oTD21.appendChild(document.createTextNode("Cell 2,1"));
oTR1.appendChild(oTD21);
var oTR2=document.createElement("tr");
oTBody.appendChild(oTR2);
var oTD12=document.createElement("td");
oTD12.appendChild(document.createTextNode("Cell 1,2"));
oTR2.appendChild(oTD12);
var oTD22=document.createElement("td");
oTD22.appendChild(document.createTextNode("Cell 2,2"));
oTR2.appendChild(oTD22);
document.body.appendChild(oTable);
</script>
这段代码十分的冗长而且有些难于理解。为了协助建立表格,HTML DOM给<table/>,<tbody/>和<tr/>等
元素添加了一些特性和方法.
给<table/>元素添加了一下内容:
caption--指向<caption/>元素
tBodies---<tbody/>元素的集合
tFoot--指向<tfoot/>元素(如果存在)
tHead--指向<thead/>元素(如果存在)
rows---表格中所有行的集合
createThead()--创建<thead/>元素并将其放入表格
createTFoot()--创建<tfoot/>元素并将其放入表格
createCaption()--创建<caption/>元素并将其放入表格
deleteTHead()--删除<thead/>元素
deleteTFoot()--删除<tfoot/>元素
deleteCaption()--删除<caption/>元素
deleteRow(position)--删除<caption/>元素
insertRow(position)--在rows集合中的指定位置插入一个新行
<tbody/>元素添加了一下内容:
rows---<tbody/>中的所有行的集合
deleteRow(position)--删除指定位置上的行
insertRow(position)--在rows集合中的指定位置插入一个新行
<tr/>元素中添加了一下内容
cells--<tr/>元素中所有的单元格的集合
deleteCell(position)--删除给定位置上的单元格
insertCell(position)--在cells集合的给定位置上插入一个新的单元格
上面的一切意味着什么?简单地说,它意味着如果使用这些简单的属性和方法就可以大大降低
创建表格的复杂度。
例:
<script>
var oTable=document.createElement("table");
oTable.setAttribute("border","1");
oTable.setAttribute("width","100%");
var oTBody=document.createElement("tbody");
oTable.appendChild(oTBody);
oTBody.insertRow(0);
oTBody.rows[0].insertCell(0);
oTBody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1,1"));
oTBody.rows[0].insertCell(1);
oTBody.rows[0].cells[1].appendChild(document.createTextNode("Cell 2,1"));
oTBody.insertRow(1);
oTBody.rows[1].insertCell(0);
oTBody.rows[1].cells[0].appendChild(document.createTextNode("Cell 2,1"));
oTBody.rows[1].insertCell(1);
oTBody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2,2"));
document.body.appendChild(oTable);
</script>
遍历DOM
到目前为止,我们讨论的功能都仅仅是DOM Level 1的部分。本节将介绍一些DOM Level 2 的功能,
尤其是和遍历DOM文档相关的DOM Level 2遍历(traversal)和范围(range)规范中的对象。这些功能只有在Mozilla
和Kongueror/Safari中才有.
NodeIterator
第一有关的对象是NodeIterator,用它可以对DOM树进行深度优先的搜索。
要创建NodeIterator对象,请使用document对象的createNodeIterator()方法.这个方法接受四个参数:
1.root-----从树中开始搜索的那个节点。
2.whatToShow----一个数值代码,代表哪些节点需要访问
3.filter-------NodeFilter对象,用来决定需要忽略哪些节点
4.entityReferenceExpansion--布尔值,表示是否需要扩展实体引用。
通过应用下列一个或多个常量,whatToShow参数可以决定哪些节点可以访问.
NodeFilter.SHOW_ALL-------显示所有的节点类型
NodeFilter.SHOW_ELEMENT---显示元素节点
NodeFilter.SHOW_ATTRIBUTE---显示特性节点
NodeFilter.SHOW_TEXT------显示文本节点
NodeFilter.SHOW_CDATA_SECTION--显示CData section节点
NodeFilter.SHOW_ENTITY_REFERENCE--显示实体引用节点
NodeFilter.SHOW_ENTITY---显示实体节点
NodeFilter.SHOW_PROCESSING_INSTRUCTION--显示PI节点
NodeFilter.SHOW_COMMENT--显示注释节点
NodeFilter.SHOW_DOCUMENT--显示文档节点
NdeeFilter.SHOW_DOCUMENT_TYPE--显示文档类型节点
NodeFilter.SHOW_DOCUMENT_FRAGMENT--显示文档碎片节点
NodeFilter.SHOW_NOTATION---显示记号节点
可以通过使用二进制或操作符来组合多个值:
var iWhatToShow=NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT;
createNodeIterator()的filter(过滤器)参数可以指定一个自定义的NodeFilter对象,
但是如果不想使用它的话,也可以留空(null).
例:
创建访问所有节点类型的NodeIterator对象
var iterator=document.createNodeIterator(document,NodeFilter.SHOW_ALL,null,false);
要在搜索过程中前进或后退,可以使用nextNode()和previousNode()方法:
var node1=iterator.nextNode();
var node2=iterator.nextNode();
var node3=iterator.previousNode();
alert(node1==node3);//ouputs "true"
<html>
<head><title>NodeIterator Example</title>
<script type="text/javascript">
var iterator=null;
function makeList(){
var oDiv=document.getElementById("div1");
iterator=document.createNodeIterator(oDiv,NodeFilter.SHOW_ELEMENT,null,false);
var oOutput=document.getElementById("text1");
var oNode=iterator.nextNode();
while(oNode){
oOutput.value+=oNode.tagName+"\n";
oNode=iterator.nextNode();
}
}
</script>
</head>
<body>
<div id="div1">
<p>Hello <b>World!</b></p>
<ul>
<li>list item1</li>
<li>list item2</li>
<li>list item3</li>
</ul>
</div>
<textarea rows="10" cols="40" id="text1"></textarea><br/>
<input type="button" value="Make List" onclick="makeList()"/>
</body>
</html>
结果:DIV P B UL LI LI LI
但假设不想在结果中包含<p/>元素。这就不能仅使用whatToShow参数来完成。这种情况下,你
需要自定义一个NodeFilter对象。
NodeFilter对象只有一个方法:acceptNode().如果应该访问给定的节点,那么该方法返回NodeFilter.FILTER_ACCEPT;
如果不应该访问给定节点,则返回NodeFilter.FILTER_REJECT.然而,不能使用NodeFilter类来创建这个对象,因为这个类
是一个抽象类。
现在,只要创建任意一个有acceptNode()方法的对象,就可以将它传给createNodeIterator()方法。
var oFilter=new Object;
oFilter.acceptNode=function(oNode){
//filter logic goes here
//禁止p
return (oNode.tagName=="p")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT
};
<html>
<head><title>NodeIterator Example</title>
<script type="text/javascript">
var iterator=null;
function makeList(){
var oDiv=document.getElementById("div1");
var oFilter=new Object;
oFilter.acceptNode=function(oNode){
//filter logic goes here
//禁止p
return (oNode.tagName=="P")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT
};
iterator=document.createNodeIterator(oDiv,NodeFilter.SHOW_ELEMENT,oFilter,false);
var oOutput=document.getElementById("text1");
var oNode=iterator.nextNode();
while(oNode){
oOutput.value+=oNode.tagName+"\n";
oNode=iterator.nextNode();
}
}
</script>
</head>
<body>
<div id="div1">
<p>Hello <b>World!</b></p>
<ul>
<li>list item1</li>
<li>list item2</li>
<li>list item3</li>
</ul>
</div>
<textarea rows="10" cols="40" id="text1"></textarea><br/>
<input type="button" value="Make List" onclick="makeList()"/>
</body>
</html>
结果:DIV B UL LI LI LI
NodeIterator对象展示了一种有序的自顶向下遍历整个DOM树的方式。然而可能想遍历到树的
特定区域时,再看看莫个节点的兄弟节点或者子节点。如果是这种情况,可以使用TreeWalker.
TreeWalker
TreeWalker有点像NodeIterator的大哥:它有NodeIterator所有的功能(nextNode()和previousNode()),
并且添加了一些遍历方法:
parentNode()------进入当前节点的父节点
firstChild()------进入当前节点的第一个子节点
lastChild()-----进入当前节点的最后一个子节点
nextSibling()---进入当前节点的下一个兄弟节点
prevousSibling()---进入当前的前一个兄弟节点
要开始使用TreeWalker,其实完全可以像使用NodeIterator那样,只要把createNodeIterator()的调用改为调用
createTreeWalker(),这个函数接受同样的参数。
例:测试失败
<html>
<head><title>TreeWalker Example</title>
<script type="text/javascript">
var walker=null;
function makeList(){
var oDiv=document.getElementById("div1");
var oFilter=new Object;
oFilter.acceptNode=function(oNode){
//filter logic goes here
//禁止p
return (oNode.tagName=="P")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT
};
walker=document.createNodeIterator(oDiv,NodeFilter.SHOW_ELEMENT,oFilter,false);
var oOutput=document.getElementById("text1");
walker.firstChild();//go to <p>
walker.nextSibling();// to to <ul>
var oNode=walker.firstChild();
while(oNode){
oOutput.value+=oNode.tagName+"\n";
oNode=walker.nextNode();
}
}
</script>
</head>
<body>
<div id="div1">
<p>Hello <b>World!</b></p>
<ul>
<li>list item1</li>
<li>list item2</li>
<li>list item3</li>
</ul>
</div>
<textarea rows="10" cols="40" id="text1"></textarea><br/>
<input type="button" value="Make List" onclick="makeList()"/>
</body>
</html>
//outputs "LI LI LI"
发表评论
-
倒计时 传入 时间戳
2011-04-14 21:32 3857//计算倒计时 ,时间戳 id function j ... -
js 表单验证
2011-04-13 11:41 1083/*表单验证 调用1 validate_form(' ... -
jQuery去掉右键菜单
2011-03-15 14:34 967//去掉右键菜单 $(document).bind ... -
Textarea ---操作
2011-03-03 09:54 1069App = {}; App.byteLengt ... -
js 滚动
2011-01-21 11:09 1027转载: http://www.popub.net/ ... -
计算汉字长度
2010-11-15 16:24 864计算汉字长度 function strLen(s ... -
JavaScript Img onload 在 IE 7 失效的解决办法.
2010-08-19 09:19 2928转自: http://blog.mmclub.net/ind ... -
Aptana javascript eclipse插件
2010-04-27 13:45 1194http://www.radrails.org/radrail ... -
Javascript 设计模式pdf 和书中代码
2010-04-19 14:27 3657Javascript 设计模式: JavaScript. ... -
javascript防止发生默认浏览器行为通用函数
2010-04-16 12:33 875防止发生默认浏览器行为通用函数: <!DOCTYPE ... -
javascrip阻止事件冒泡的通用函数
2010-04-16 11:27 1030javascrip阻止事件冒泡的通用函数: <!DOC ... -
原型式继承的例子
2010-04-15 10:44 1286原型式继承的例子: <script>//为Pers ... -
set和get方法动态添加,这些方法在新对象实例化时创建
2010-04-15 09:54 1349动态生成方法的例子,这些方法在新对象实例化时创建: //创建 ... -
使用构造函数属性来判断对象的类型
2010-04-14 16:11 1038使用构造函数属性来判断对象的类型: //检查我们的数字 ... -
arguments 示例:一个接受任意数量参数并将其转为数组的函数
2010-04-12 15:07 1108一个接受任意数量参数并将其转为数组的函数: JavaScri ... -
模仿--凤凰网图片集
2010-03-30 23:09 1727凤凰网图片集: http://news.ifeng.com/p ... -
对联广告效果
2010-02-05 13:04 877转载: <!DOCTYPE html PUBLIC &q ... -
javascript 学习笔记五 第七章 正则表达式
2009-10-30 14:57 1432第七章 正则表达式 JavaScript对正则表达式的支持 ... -
javascript 学习笔记三 浏览器中的JavaScript
2009-10-23 09:34 940第五章 浏览器中的JavaScript BOM(浏览器对象模 ... -
getQueryParamValue 得到URL中的参数类似 request.getParamater("videoid")
2009-10-23 09:31 1539<html> <head> &l ...
相关推荐
在这个学习笔记中,涵盖了从基础到高级的JavaScript和DOM操作技巧,一共涉及1~9章的内容。以下是对这些章节知识点的详细阐述: **第1章:JavaScript简介** 本章介绍了JavaScript的基本概念,包括它是一种解释型、弱...
JavaScript学习笔记是一本关于JavaScript编程语言的教材,该教材通过丰富的实例,系统地介绍了JavaScript的基础知识和实际应用技巧,帮助读者一步步掌握客户端编程技术。本书共分为九章,每一章都有其特定的主题,...
### JavaScript基础知识点详解 #### 一、JavaScript简介 **JavaScript**是一种主要运行在客户端的脚本语言,它不需要经过编译就能直接由浏览器解析执行。这使得JavaScript成为了现代Web开发中不可或缺的一部分,...
文档对象模型(DOM)是JavaScript在浏览器环境中与HTML文档交互的核心机制。DOM是一种标准,它定义了HTML和XML文档的结构,并提供了编程接口,使得我们可以用脚本语言(如JavaScript)来操纵文档的内容、结构和样式...
### JavaScript DOM 学习笔记知识点总结 #### 一、DOM基础概述 DOM(Document Object Model)文档对象模型是一种处理可扩展标记语言的标准编程接口。它提供了结构化文档(如HTML和XML)的标准方法来访问、修改文档...
JavaScript,简称JS,是由Brendan Eich在1995年创造的一种高级编程语言,最初目的是为了增强网页的交互性,特别是在前端进行表单验证。...这些类型构成了JS编程的基础,理解和掌握它们是学习JavaScript的第一步。
### JavaScript 学习笔记 #### 一、JavaScript 概述 **JavaScript** 是一种轻量级的编程语言,主要用于网页的交互式开发。它是一种解释型的语言,可以在客户端(通常是浏览器)运行,也可以在服务器端运行(如 ...
### JavaScript DOM 编程知识点详解 #### 一、DOM 基础概念 **DOM (Document Object Model)** 是一种用于表示 HTML 和 XML 文档的标准对象模型。它将文档定义为节点树,允许开发者通过编程方式访问和修改这些节点...
本学习笔记全面涵盖了JavaScript的语法和用法,旨在帮助初学者快速掌握并深入理解这门语言。 一、基础语法 JavaScript的基础包括变量、数据类型、操作符和流程控制。变量在JavaScript中使用`let`、`const`和`var`...
现在我们专注于《jQuery权威指南》第三章——jQuery操作DOM的内容。DOM,即文档对象模型,是HTML和XML文档的编程接口,它将文档结构转换为一个树形结构,方便程序进行读取和修改。jQuery提供了丰富的API,让开发者...
JavaScript学习笔记 JavaScript是一种强大的、跨平台的编程语言,主要用于为网页和应用程序添加交互性。在Web开发中,JavaScript与HTML和CSS一起构成了基础的三驾马车。本教程将帮助初学者理解JavaScript的核心概念...
JavaScript是一种广泛应用...以上就是JavaScript学习笔记中的主要知识点,理解和掌握这些内容对于深入学习JavaScript至关重要。在实际编程中,还需要结合具体的场景灵活运用,并不断实践和探索更高级的特性和最佳实践。
《李炎恢JavaScript-pdf文档笔记》是一份详细记录了JavaScript编程语言基础知识至高级应用的教程,涵盖了从第一章到第三十四章的丰富内容。这个压缩包包含了一份PDF文档,旨在帮助学习者深入理解并掌握JavaScript的...
JavaScript DOM 学习笔记 JavaScript DOM(Document Object Model)是 HTML 和 XML 文档的编程接口,它提供了一种访问和操作文档结构和内容的方式。DOM 将文档表示为一个树状结构,其中每个节点都代表文档中的一个...
以上只是JavaScript学习笔记的部分内容,JavaScript还包括DOM操作、事件处理、Ajax异步通信、Promise、async/await、模块化(CommonJS、ES模块)、闭包、作用域链等丰富知识。深入学习JavaScript将帮助开发者构建更...
在本章"Eclipse开发学习笔记第17章源码"中,我们将深入探讨如何使用Eclipse集成开发环境(IDE)来构建一个实际的在线购物系统。这个实例将涵盖多个关键的IT知识点,包括软件工程的设计原则、Java编程、Web应用程序...
这本“JavaScript高级程序设计第四版”的学习笔记涵盖了JavaScript的各个方面,旨在帮助学生、开发者以及对编程感兴趣的人深入理解这一强大的脚本语言。这份笔记是针对毕设、课设、项目实训等实践性学习场景编写的,...
### JavaScript基础知识点总结 #### 一、语言概念与发展历程 - **语言定义**:计算机语言是一种人与计算机之间沟通的工具。人们通过编程语言来控制和操作计算机完成特定任务。 - **语言发展历史**: - **早期阶段...
2. **Function对象**:在JavaScript中,函数是第一类对象,意味着函数可以作为变量赋值、作为参数传递和作为其他函数的返回值。Function对象可以用来创建新的函数,例如`new Function("arg1", "arg2", "return arg1 ...