JS DOM节点

来源:互联网 发布:金融互助平台源码 编辑:程序博客网 时间:2024/06/15 19:39

Node类型

JS中的所有节点都继承了Node节点的属性和方法,均有一个表示节点类型的nodeType属性,这些属性的值可以取为下列常量或者对应数值;

node.nodeType   // 1;node.nodeValue  // nullnode.ownerDocument  // #document
Node.ELEMENT_NODE                    --->  1   --->  元素节点                    Node.ATTRIBUTE_NODE                 --->  2   --->  属性节点Node.TEXT_NODE                      --->  3   --->  文本节点Node.CDATA_SECTION_NODE             --->  4   --->  文档中的CDATA区段节点Node.ENTITY_REFERENCE_NODE          --->  5   --->  实体引用节点Node.ENTITY_NODE                    --->  6   --->  实体节点Node.PROCESSING_INTRODUCTION_NODE   --->  7   --->  处理指令节点Node.COMMET_NODE                    --->  8   --->  注释节点Node.DOCUMENT_NODE                  --->  9   --->  文档节点Node.DOCUMENT_TYPE_NODE             --->  10  --->  文档类型节点Node.DOCUMENT_FRAGEMENT_NODE        --->  11  --->  文档片段节点Node.NOTATION_NODE                  --->  12  --->  DTD声明节点

节点都有nodeName和nodeValue属性;对于元素节点nodeName保存的是元素的标签名,元素节点的nodeValue的值始终为null;

每个节点都需要一个childNodes,保存着一个的类数组对象NodeList,返回的是基于DOM结构动态执行查询的结果;另外也可以通过item(index)方法访问;node.childNodes.item(index);

节点的常用属性: childNodes/ parentNode/ previousSibling/ nextSibling/ firstChild/ lastChild/ ownerDocument指向整个文档的文档节点/
节点的常用方法
node.hasChildNodes()无参方法,有子节点时返回true,否则为false;
node.appendChild()方法返回新增节点,用于向childNodes列表末尾添加一个节点;
node.insertBefore(newNode, referNode): 接受两个参数,分别为要插入的节点和作为参照的节点;插入节点将变为参考节点的前一个兄弟节点; 同时会返回新插入的节点;如果参考节点为null,则insertBefore()与appendChild()作用相同;如果新节点存在,那么新节点的位置会更新到当前位置;
node.replaceChild(newNode, replaceNode); 接受两个参数新节点和被替换节点,返回的是被替换节点;
node.removeChild(removedNode): 移除节点;虽然移除的节点已经不在文档树中,但其仍然属于文档所有;

所有类型节点共有的两个方法:
1、node.cloneNode(boolean)方法接收一个布尔值作为参数,true则为深拷贝,返回的是节点的副本,包括其子节点树;该副本是一个孤立节点,属于文档所有,但是需要调用上述方法才能将其加入到文档树中;cloneNode()方法不会复制DOM对象的JS属性,但是IE会复制事件处理程序,因此需要在拷贝时解除绑定的事件处理程序;
2、node.normalize():该方法仅可以处理文档树中的文档节点,如果有两个相邻的节点,调用该方法会将这两个节点合并;如果文本节点为空,调用该方法会删除空文本节点;

var wrapper = document.createElement('div');textNode1 = document.createTextNode('text1');textNode2 = document.createTextNode('text2');wrapper.appendChild(textNode1);wrapper.appendChild(textNode2);wrapper.childNodes.length;  // 2wrapper.normalize();wrapper.childNodes.length;  // 1

IE<9的浏览器版本中不会对空字符串创建文本节点,因此下例中node.childNodes.length返回4,其他浏览器返回9;

    <ul class="list">        <li>HTML</li>        <li>CSS</li>        <li>JS</li>        <li>JAVA</li>    </ul>

这里写图片描述


Document类型

document对象表示整个HTML页面,是HTMLDocument的实例;通过document.documentElement可以直接访问到<html>元素;document.body可以直接访问到<body>元素;这两个方法所有的浏览器都支持;另外,还有一个doctype属性不同的浏览器实现之间存在很大差别;

window.document instanceof window.HTMLDocument  // true;node.nodeType   // 9node.nodeName   // #documentnode.nodeValue  // nullnode.parentNode // nullnode.ownerDocument  //null

访问文档属性的方法:
document.domain是可写的,仅可以将其由tight域名改为loose域名,这样一般用于同一父级域名下不同框架之间的通信;

document.titledocument.URL        // 页面完整URL "https://www.baidu.com/"document.domain     // 页面域名 "www.baidu.com"document.referrer   // 链接到当前页面的URL

查找元素: document.getElementById() 和 document.getElementByTagName();
1、getElementById()方法对传入的参数区分大小写,查找失败返回null;IE8及以下版本则不区分ID大小写;

IE中关于getElementById()的问题
在浏览器IE7及较低版本的IE浏览器中,如果存在表单元素(input/ button/ select/ textarea)的name特性等于目标元素的ID,并且该表单元素位于目标元素前,那么在这些浏览器中会返回表单元素而不是目标元素;

<input type="text" name="targetElement" value="name"><div id="targetElement">hello World</div>

IE7及以下版本中返回input元素;其他浏览器正常返回目标元素;

2、getElementsByTagName()方法返回一个HTMLCollection对象,这也是一个类数组对象;可以传入‘*’获取文档中所有元素;除了document有该方法外,元素也有该方法;

3、一些特殊属性:document.anchors获取所有带name属性的<a>元素; document.forms包含文档中所有的<form>元素;document.images获取所有<img>元素;document.links包含文档中所有带href属性的<a>元素;

DOM一致性检测
使用document.implementation具有hasFeature()方法,接受两个参数分别表示DOM功能及相应的版本号,返回值为Boolean类型;
建议同时使用浏览器能力检测;


Element类型

Element类型提供了对元素标签名、子节点及特性的访问;nodeType为1,node.nodeName === node.tagName;
在HTML中标签名是大写形式表示,在XML中则与XML文档中的命名一样;
2、关于属性设置的方法:node.getAttribute()/ setAttribute()/ removeAttribute(),属性名称不分大小写,HTML5规范中自定义的属性名需要加入data-前缀
3、document.createElement用于创建元素,IE中则可以使用createElement(),不过参数不同,它接收的参数为为包含属性的完整标签;

createElement("<div id=\"myDiv\" class=\"myClass\"></div>"

IE8以下的版本(不包含IE8)创建元素的一些兼容性问题: 动态创建的<iframe>元素不能设置其name属性,因此需要创建时同时指定这些属性;动态创建的<input>不可以通过reset()方法重新设置;


Attr类型

创建属性节点可以使用document.createAttribute()方法,传入的是属性名,设置属性可以使用attr.value;该节点具有三个属性name, value, specified(用于确认一个属性是默认属性还是代码指定的);


Text类型

TextNode的parentNode为Element结点,没有子节点;

nodeType    // 3nodeName    // '#text'nodeValue   // 对应的包含文本// 文本节点处理方法appendData(text);deleteData(offset, count);insertData(offset, text);replaceData(offset, count, text)splitText(text);    //分割文本节点是从中提取数据的常用的DOM解析技术;subStringData(offset, count)

Comment

注释节点,没有子节点;可以通过nodeValue或者data属性取得该内容。可以通过document.createComment(text)创建注释节点;

nodeType    // 8nodeName    // "#comment"nodeValue   // 注释内容// html<div id="cNode"><!-- this is a comment --></div>// JSvar node = document.getElementById('cNode');var comment = node.firstChild;console.log(comment.data === comment.nodeValue);

DocumentType类型

没有子节点;

nodeType    // 10nodeName    // docTypenodeValue   // nullparentNode  // Document

DocumentFragment类型
创建文档片段类型可以使用document.createDocumentFragment()方法;该类型继承了Node的所有方法;文档片段本身不会成为文档树的一部分;
使用文档片段的方式可以避免浏览器的反复渲染,仅进行一次渲染更新;

nodeType    //  11nodeName    // "#document-fragment"nodeValue   // nullparentNode  // null

这里写图片描述

上例中为了向<ul>添加三个<li>子元素,先创建一个文档片段节点,然后分别创建li节点并将其添加到文档片段节点中,然后将该列表添加到文档片段中;最后将文档片段添加到ul中;此时文档片段中的所有子节点都被删除并转移到<ul中;

创建动态脚本存在一定的兼容性问题,在IE中<script>元素为一个特殊元素,无法通过DOM访问其子节点,因此无法使用appendChild()属性,可以用text属性包好相应的脚本代替;

var script = document.createElement('script');script.type = 'text/javascript';var code = "function f() {console.log('hello');}";try {    script.appendChild(document.createTextNode(code));} catch (ex) {    script.text = code;}

同样地,创建动态样式也具有相似的问题,可以使用下面的代码实现兼容

var style = document.createElement('style');style.type = 'text/css';try {    style.appendChild(document.createTextNode("body{background-color:red}"));} catch (ex) {    style.stylesheet.cssText = "body{background-color:red}";}

创建表格

DOM中定义了专门简化表格相关的一些属性和方法,tBodied/ tFoot/ tHead/ rows/ caption/ createTHead()/ createTFoot()/ createCaption()/ deleteTHead()/ deleteTFoot()/ deleteCaption()/ deleteRow(index)/ insertRow(index)/ rows/ deleteRow(index)/ insertRow(index)/ cells/ deleteCell(index)/ insertCell(index)。

/* 创建表格 */// 创建tablevar table = document.createElement("table");table.border = 1;table.width = "100%";// 创建tbodyvar tbody = document.createElement("tbody");table.appendChild(tbody);// 创建一行tbody.insertRow(0);tbody.rows[0].insertCell(0).appendChild(document.createTextNode("(1,1)"));tbody.rows[0].insertCell(1).appendChild(document.createTextNode("(1,2)"));// 创建另一行tbody.insertRow(1);tbody.rows[1].insertCell(0).appendChild(document.createTextNode("(2,1)"));tbody.rows[1].insertCell(1).appendChild(document.createTextNode("(2,2)"));document.body.appendChild(table);

NodeList/ NamedNodeMap/ HTMLCollection会随着文档内容的更新动态更新
这里写图片描述

这里首先获取了HTMLCollection动态对象,每次动态地插入div元素到文档中后,HTMLCollection列表对象都会更新,那么每次循环后变量i和divs.length就会同时更新,那么这就是一个死循环;

原创粉丝点击