DOM详解

前言
  DOM(文档对象模型),用来将HTML和XML文档描绘成一个层次化的节点数,允许开发人员添加、删除或修改页面的内容。IE中的DOM对象是通过COM对象的形式实现的,因此IE的DOM对象与JS对象的行为特点并不一致。
节点类型
常见的四个节点类型:Node.ELEMENT_NODE(1)、Node.ATTRIBUTE_NODE(2)、Node.TEXT_NODE(3)、Node.DOCUMENT_NODE(9)。
在IE8-中不能直接访问节点类型名称(Node.ELEMENT_NODE)。在判断节点类型时最好以数字值(1)比较。
1 <div id="div"></div>
2 <script>
3     console.log(document.getElementById('div').nodeType); // 1
4     console.log(document.getElementById('div').nodeType == Node.ELEMENT_NODE); // true IE8-中会报错Node未定义
5     console.log(document.getElementById('div').nodeType == 1); // true
6 </script>
View Code
nodeName:
  元素节点的nodeName是标签名;
  属性节点的nodeName是属性名;
  文本节点的nodeName始终是#text;
  文档节点的nodeName始终是#document。
1 <div id="div">11</div>
2 <script>
3     console.log(document.getElementById('div').nodeName); // DIV
4     console.log(document.getElementById('div').getAttributeNode('id').nodeName); // id
5     console.log(document.getElementById('div').childNodes[0].nodeName); // #text
6     console.log(document.nodeName); // #document
7 </script>
View Code
nodeValue:
  文本节点的nodeValue是文本内容;
  属性节点的nodeValue是属性值;
  元素节点的nodeValue是null,
  文档节点的nodeName是null。
1 <div id="div">11</div>
2 <script>
3     console.log(document.getElementById('div').nodeValue); // null
4     console.log(document.getElementById('div').getAttributeNode('id').nodeValue); // div
5     console.log(document.getElementById('div').childNodes[0].nodeValue); // 11
6     console.log(document.nodeValue); // null
7 </script>
View Code
NOTE:在通过nodeName来检查是否为某元素时最好先检测nodeType等于1。
节点关系
childNodes:
  childNodes可以动态执行查询结果,当DOM结构变化时能自动反映出来。
  可以通过方括号或item()方法来访问childNodes中的某个节点。
 1 <div id="div">
 2     11
 3     <span>11111111</span>
 4     22
 5 </div>
 6 <script>
 7     console.log(document.getElementById('div').childNodes); // 如下图
 8     console.log(document.getElementById('div').childNodes[1].nodeType); // 1
 9     console.log(document.getElementById('div').childNodes.item(1).nodeType); // 1
10     console.log(document.getElementById('div').childNodes.length); // 3
11     document.getElementById('div').innerHTML += '<span>22222222</span>';
12     console.log(document.getElementById('div').childNodes.length); // 4
13 </script>
View Code
  如图所示:后添加一个span也能动态的显示在childNodes中。
parentNode:父节点
previousSibling:上一个兄弟节点(上一个没有就是null)
nextSibling:下一个兄弟节点(下一个没有就是null)
firstChild:第一个子节点(没有子节点为null)
lastChild:最后一个子节点(没有子节点为null)
hasChildNodes:有一个或多个子节点时返回true,比查询childNodes.length更高效。
 1 <div id="div1"></div>
 2 <div id="div2"> </div>
 3 <div id="div3">
 4 
 5 
 6 </div>
 7 <script>
 8     console.log(document.getElementById('div1').hasChildNodes()); // false
 9     console.log(document.getElementById('div2').hasChildNodes()); // true   IE8- false(在IE8-空文本不会当作节点,标准浏览器是节点)
10     console.log(document.getElementById('div3').hasChildNodes()); // true   IE8- false(在IE8-空文本不会当作节点,标准浏览器是节点)
11 </script>
View Code
 ownerDocument:该属性指向文档节点。当访问文档节点时可以通过节点的这个属性来查找提升效率。
1 <div id="div1"></div>
2 <script>
3     console.log(document.getElementById('div1').ownerDocument); // #document
4 </script>
View Code
操作节点
appendChild:在childNodes末尾添加一个节点,返回新增的节点,如果新节点是已有的节点那么该节点的原位置会被删除。
 1 <div id="div">div</div>
 2 <ul id="ul">
 3     <li id="li1">1</li>
 4     <li id="li2">2</li>
 5     <li id="li3">3</li>
 6 </ul>
 7 <script>
 8     var oLi = document.createElement('li'),
 9             oUl = document.getElementById('ul'),
10             oDiv = document.getElementById('div'),
11             oLi1 = document.getElementById('li1');
12     oLi.innerHTML = '4';
13 
14     console.log(oUl.appendChild(oLi)); // <li>4</li> 返回新增的元素
15     console.log(oUl.appendChild(oLi1)); // <li id="li1">1<div id="div">div</div></li> 返回新增的元素  动态显示了div
16     console.log(oLi1.appendChild(oDiv)); // <div id="div">div</div> 返回新增的元素  
17 </script>
View Code
最后的DOM结构:
insertBefore:插入节点。返回被插入的节点。如果参照节点为null,insertBefore和appendChild一样。
 1 <ul id="ul">
 2     <li id="li1">1</li>
 3     <li id="li2">2</li>
 4     <li id="li3">3</li>
 5 </ul>
 6 <script>
 7     var oLi = document.createElement('li'),
 8             oUl = document.getElementById('ul');
 9     oLi.innerHTML = '4';
10 
11     console.log(oUl.insertBefore(oLi, null)); // <li>4</li> 返回被插入的元素  插入最后
12     console.log(oUl.insertBefore(oLi, oUl.firstChild)); // <li>4</li> 返回被插入的元素  插入前面
13     console.log(oUl.insertBefore(oLi, oUl.lastChild)); // <li>4</li> 返回被插入的元素  插入最后一个的前面
14 </script>
View Code
replaceChild:替换节点。返回被替换的节点。节点被替换后,该节点还是存在文档中,如果节点不适用了应当将其销毁。
1 <ul id="ul"><li id="li1">1</li><li id="li2">2</li><li id="li3">3</li></ul>
2 <script>
3     var oLi = document.createElement('li'),
4             oUl = document.getElementById('ul');
5     oLi.innerHTML = '4';
6 
7     console.log(oUl.replaceChild(oLi, oUl.firstChild)); // <li id="li1">1</li> 返回被替换的元素
8     console.log(oUl.replaceChild(oLi, oUl.lastChild)); // <li id="li3">3</li> 返回被替换的元素
9 </script>
View Code
 removeChild:删除节点。返回被删除的节点。节点被删除后,该节点还是存在文档中,如果节点不适用了应当将其销毁。
cloneNode:复制节点。可以传递一个boolean值,true深度复制会复制所有的子节点,false浅度赋值不会复制子节点。该方法不能复制通过js添加的属性和事件。
1 <ul id="ul"><li id="li1">1</li><li id="li2">2</li><li id="li3">3</li></ul>
2 <script>
3     var oUl = document.getElementById('ul');
4 
5     console.log(oUl.cloneNode(false)); // <ul id="ul"></ul> 浅度复制
6     console.log(oUl.cloneNode(true)); // <ul id="ul"><li id="li1">1</li><li id="li2">2</li><li id="li3">3</li></ul> 深度复制
7 </script>
View Code
 1 <ul id="ul" onclick="alert(1)"><li id="li1">1</li><li id="li2">2</li><li id="li3">3</li></ul>
 2 <script>
 3     var oUl = document.getElementById('ul');
 4     oUl.onmouseover = function(){this.style.background = 'red';} // 该事件未被复制
 5 
 6     console.log(oUl.cloneNode(false)); // <ul id="ul"></ul> 浅度复制
 7     console.log(oUlClone = oUl.cloneNode(true)); // <ul id="ul"><li id="li1">1</li><li id="li2">2</li><li id="li3">3</li></ul> 深度复制
 8 
 9     document.body.appendChild(oUlClone); // onclick事件被复制了
10 </script>
View Code
document类型
1、访问html:document.documentElement、document.firstChild、document.childNodes[0] 其中document.documentElement的效率最高
2、访问body:document.body
3、文档类型:document.doctype(兼容性很差)
4、title属性:document.title
5、URL地址:document.URL
6、域名:document.domain
7、链接到当前页面的页面:document.referrer
1     console.log(document.URL); // url
2     console.log(document.domain); // 域名
3     console.log(document.referrer); // 链接到本页的url
 8、getElementById:根据元素ID获取元素,没有返回null。
  1、IE8-的id不区分大小写,标准浏览器区分大小写。
  2、页面多个元素id相同时,返回第一个。
  3、IE7-中表单元素的name值与某个元素的ID值相同时,如果name在前会返回name对应的表单元素。
1 <div name="test" class="div1"></div><!-- IE7- div的name不能获取 -->
2 <input type="button" name="test" class="button1"/>
3 <div id="test" class="div2"></div>
4 <script>
5     console.log(document.getElementById('test').className); // div2  IE7- button1
6 </script>
View Code
9、getElementsByTagName:获取的元素是动态的,可以通过[index]、[name]、item(index)、namedItem(name)方法来访问某个元素。
 1 <img name="test1">
 2 <img name="test2">
 3 <img name="test3">
 4 <img name="test4">
 5 <script>
 6     console.log(document.getElementsByTagName('img')[0].name); // test1
 7     console.log(document.getElementsByTagName('img')['test1'].name); // test1
 8     console.log(document.getElementsByTagName('img').item(0).name); // test1
 9     console.log(document.getElementsByTagName('img').namedItem('test1').name); // test1
10 </script>
View Code
 一些集合:
1、document.anchors:返回页面中带有name属性的a元素;
2、document.forms:返回页面中的所有form元素;
3、document.images:返回页面中的所有img元素;
4、document.links:返回页面中所有带href属性的a元素。
元素类型
1、tagName/nodeName:返回元素的标签名(注意返回的值可能是大写也可能是小写)。
2、getAttribute、setAttribute、removeAttribute操作元素的属性
  ①、此时的class就直接用class而不用className
  ②、属性名不区分大小写
  ③、在html5中规定自定义属性名加上data-以便通过验证
  ④、通过getAttribute获取style和事件处理函数返回的是字符串代码,而通过DOM.style和DOM.onclick返回的确是对象和函数
  ⑤、通过DOM.设置的自定义属性值,通过getAttribute来获取只能得到null
 1 <div id="div" style="font-size: 20px;">div</div>
 2 <script>
 3     var oDiv = document.getElementById('div');
 4     oDiv.onclick = function(){
 5         console.log(this.tagName);
 6     };
 7     console.log(typeof oDiv.getAttribute('onclick')); // object null(IE7-两种方法返回值一样)
 8     console.log(typeof oDiv.onclick); // function
 9     console.log(typeof oDiv.getAttribute('style')); // string (IE7-两种方法返回值一样)
10     console.log(typeof oDiv.style); // object
11 </script>
View Code
1 <div id="div">div</div>
2 <script>
3     var oDiv = document.getElementById('div');
4     oDiv.index = 1;
5     console.log(oDiv.getAttribute('index')); // null(IE8-两种方法返回值一样)
6     console.log(oDiv.index); // 1
7 </script>
View Code
3、removeAttribute:IE6不支持。
原文地址:https://www.cnblogs.com/tyxloveyfq/p/4330720.html