• 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不支持。
  • 相关阅读:
    当梦想渐行渐远的时候
    android开发系列之aidl
    看到这页代码,我要疯了
    android开发系列之性能优化
    近期的一个项目反思与总结
    IOS中摇一摇实现截屏(可实现问题反馈的功能)
    IOS设计模式浅析之外观模式(Facade)
    IOS项目开发中的文件和文件夹操作
    XCode 4.6下XIB文件提示“...could not be opened..."的问题
    "Xcode"意外退出
  • 原文地址:https://www.cnblogs.com/tyxloveyfq/p/4330720.html
Copyright © 2020-2023  润新知