DOM节点
-
节点(Node)类型
Node接口定义了对应不同节点类型的12个常量(它们会在nodeType特性中使用到),IE中没有定义这些常量,不过我们可以自己定义。
if (typeof Node == undefined) { 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特性
常用的Node特性介绍(中括号里是其类型):
- nodeName:节点的名字(根据节点类型而定义)【String】
- nodeValue:节点的值(根据节点类型而定义)【String】
- nodeType:节点的类型常量值之一【String】
- ownerDocument:指向这个节点所属的文档【Document】
- childNodes:所有子节点集合【NodeList】
- firstChild:指向childNodes集合中的第一个节点【Node】
- lastChild:指向childNodes集合中的最后一个节点【Node】
- previousSibling:指向前一个兄弟节点,没有则为null【Node】
- nextSibling:指向后一个兄弟节点,没有则为null【Node】
- attributes:一个元素的特性的Attr对象,仅用于Element节点类型【NamedNodeMap】
在childNodes集合中有一个length属性可以用来显示子节点的个数,比如页面上有如下元素:
<div id="box-number"> <p>one</p> <p>two</p> <p>three</p> </div>
下面代码是获取上面div中子节点的个数:
var boxNum = document.getElementById('box-number'); alert(boxNum.childNodes.length); // 输出3
-
Node方法
常用的Node方法介绍(中括号里是其返回类型):
- hasChildNodes():当childNodes集合包含一个或多个节点时返回true【Boolean】
- appendChild(node):将node添加到childNodes的末尾【Node】
- removeChild(node):从childNodes中删掉node【Node】
- replaceChild(new, old):将childNodes中的old节点替换成new节点【Node】
- insertBefore(new, ref):在childNodes中的red节点前插入new节点【Node】
注意在使用appendChild(node)方法时,如果node已经在childNodes当中时,并不会再次添加node节点,而只是将node节点移到childNodes的末尾。
var boxNum = document.getElementById('box-number'), pOne = boxNum.childNodes[0]; boxNum.appendChild(pOne); // 最后会显示<p>two</p><p>three</p><p>one</p>
-
处理元素节点的特性
DOM中定义了四个元素方法来操作元素的特性:
- getAttribute(name):获取特性节点;
- setAttribute(name, value):设置特性节点;
- removeAttribute(name):移除特性节点;
- createAttribute(name):创建特性节点。
例如获取上面div中的id特性:
alert(boxNum.getAttribute('id')); // 输出box-number -
创建和操作节点
DOM中常用到的创建节点的方法包括:
- createElement(target):创建标签名为target的元素节点;
- createTextNode(text):创建包含文本为text的文本节点;
- createDocumentFragment():创建文档碎片节点。
-
createElement,createTextNode,appendChild
比如要在上面的id为box-number的div中的末尾添加一个新元素<p>four</p>:
var pFour = document.createElement('p'), text = document.createTextNode('four'); pFour.appendChild(text); boxNum.appendChild(pFour);
-
removeChild,replaceChild,insertBefore
移除节点、替换节点和在某节点前插入节点:
boxNum.removeChild(pOne); // 移除节点<p>one</p> var pFive = document.createElement('p'), text = document.createTextNode('five'); pFive.appendChild(text); boxNum.replaceChild(pFive, pFour); // 将节点<p>four</p>替换成<p>five</p> boxNum.insertBefore(pFour, pFive); // 在节点<p>five</p>前添加节点<p>four</p>
-
实现insertAfter功能
利用appendChild方法和insertBefore方法可以实现insertAfter方法:
/** * 在某个节点后插入一个新节点 * * @param Node newNode 要插入的新节点 * @param Node ref DOM中已经存在的节点 * @return Node */ function insertAfter(newNode, ref) { ref.nextSibling ? ref.parentNode.insertBefore(newNode, ref.nextSibling) : ref.parentNode.appendChild(newNode); }
-
createDocumentFragment
在进行添加节点操作时,第添加一个节点,页面就会更新并反映出这个变化。对于少量的更新,这是很好的,然而,当要向DOM中添加大量数据时,如果逐个进行添加,这个过程就会十分缓慢。为此,可以创建一个文档碎片,把所有的新节点附加在其上,然后一次性地将文档碎片添加到DOM中。
var nameList = ['cctv', 'asdf', 'keal', 'jack', 'rose'], i, ii = nameList.length, nameP, text; for (i = 0; i < ii; i++) { nameP = document.createElement('p'); text = document.createTextNode(nameList[i]); nameP.appendChild(text); document.body.appendChild(nameP); }
上面这段代码虽然运行良好,但它调用了5次document.body.appendChild()方法,每次都会产生一次页面更新。这时创建碎片文档就显得十分有用:
var nameList = ['cctv', 'asdf', 'keal', 'jack', 'rose'], i, ii = nameList.length, nameP, text, fgm = document.createDocumentFragment(); for (i = 0; i < ii; i++) { nameP = document.createElement('p'); text = document.createTextNode(nameList[i]); nameP.appendChild(text); fgm.appendChild(nameP); } document.body.appendChild(fgm);
上面代码中每个新的p元素都先添加在文档碎片中,最后调用document.body.appendChild()方法来一次性地将碎片中的子节点添加到DOM中,这意味着只需要进行一次页面更新。
浙公网安备 33010602011771号