DOM入门篇

什么是DOM?


1.  DOM的全称  Document Object Model

2.  DOM定义了表示和修改文档所需的方法。

3.  DOM对象即为宿主对象,由浏览器厂商定义,用来操作html和xml功能的一类对象的集合,也有人称DOM是对HTML和XML的标准编程接口。

DOM修改不了CSS样式表,只能通过间接的方式修改HTML中的行间样式。


节点的类型

每个节点都会有对应的数值,

元素节点   -----   1     (例如htnl里的标签,script,body,div,p...)

属性节点   -----   2     (...)

文本节点   -----   3     (标签中的间隔就是文本节点类型的...)

注释节点   -----   8      (文档中的注释)

document   -----   9

DocumentFragment   -----   11


节点的四个属性


一段仅供测试使用的代码



测试

文字

1. nodeName

判断元素的节点类型,元素的标签名以大写的形式表示(只读)

DOM入门篇_第1张图片


2. nodeValue

Text 节点或 Comment(注释) 节点才有的属性,可读写文本内容。

DOM入门篇_第2张图片


3. nodeType

判断节点的类型

每个节点类型都对应一个值,可以使用nodeType查看。

DOM入门篇_第3张图片


4. attributes

Element节点的属性结合。

把元素节点当作属性放到一个类数组里。

DOM入门篇_第4张图片

5.   Node.hasChildNodes()

这是一个方法,用来判断元素有没有子节点。有的话返回true,反之返回false


DOM的基本操作


1.  使用方法选择元素


¤  document代表整个文档

    html标签也在document之内

¤  document.getElementById('')  //  选择对应的id元素。

    扩展:元素ID在IE8以下的浏览器,不区分大小写。而且name属性的元素可以当成id元素使用。

¤  document.getElementsByTagName('')  //  选择对应的标签元素。

    选择后会是一个类数组

¤  document.getElementsByName('')  //选择对应的name属性元素,

    常用的标签(有表单,表单元素,img,iframe)

¤  document.getElementsByClassName('') 

    ·//根据类名选择元素,ie8及以下版本不支持

##凡是选出来的是一组元素的,都需要以数组的方式来调用,例如:

document.getElementsByTagName('')[0];

¤  document.querySelector()  选出来的是一个元素

¤   document.querySelectorAll()  选出来的是一组元素

    这两个方法功能一样的,都是根据选择器来选择元素

    参数里正常填写  CSS选择器  ,例如

文字


缺点:

IE7及以下版本不支持。不实时,相当于把现有的选择器做了一个副本,即使后续在添加或者是删除,也不会影响这个备份里的元素。

可以正常操作HTML中标签,不经常使用。


不一定非要使用方法选择元素,也可以使用遍历节点...


2. 遍历节点树

¤  parentNode  (最顶端的为#document)

每个DOM元素身上都有这个属性,里面存储的是它的父节点。



文字

控制台测试输出

DOM入门篇_第5张图片


¤  childNodes  (子节点组)



测试

文字

控制台测试输出body的子节点组



¤  lastChild (选择最后一个子节点)

¤  firstChild (选择第一个子节点)

控制台测试输出body的最后一个节点和第一个节点

DOM入门篇_第6张图片


¤  nextSibling (后一个兄弟节点)

¤  previousSibling  (前一个兄弟节点)

使用以上代码控制台测试:

DOM入门篇_第7张图片


3. 遍历元素节点树

¤ parentElement  返回当前元素的父元素节点(IE9以下不兼容

¤  children  返回当前元素节点的元素子节点

¤ firstElementChild  返回父级元素第一个元素节点(IE9以下不兼容

¤ lastElementChild  返回父级元素最后一个元素节点(IE9以下IE不兼容

¤ previousElementSibling  返回前一个兄弟元素节点IE9以下IE不兼容

¤ nextElementSibling  返回后一个兄弟元素节点IE9以下IE不兼容



4.DOM继承树

document 的构造函数是 HTMLDocument ,HTMLDocument构造函数的原型是 HTMLDocument {…}

HTMLDocument {…}(原型)  的 __proto__  里有Document

Document  里的  __proto__  里有  Node

一直看下去的话会发现最终原型是  Object{...}  

继承树表示的其实是一种继承关系,

DOM入门篇_第8张图片

1. getElementById  方法定义在 Document.prototype 上,即 Element 节点上不能使用。

说明HTML和XHTML都可以使用 getElementById

2. getElementsByName 方法定义在 HTMLDocument.prototype 上,即非 html  中的  document不能使用(xhtml...)

3. getElementsByTagName 方法定义在 Document.prototype 和 Element.prototype 上document和标签Element元素都可以调用getELementByTagName

4. HTMLDocument.prototype 定义了一些常用的属性,body , head 分别指代HTML文档中的标签

document.body 和 document.head 分别指的是body标签和head标签

5. Document.prototype 上定义了 documentElement 属性,指代文档的根元素,在HTML文档中,它总是指代元素

document.documentElement 指的是 html 标签

6. getElementsByName , querySeleCtorAll , querySelector 在 Document.prototype, Element.prototype 类中有定义。



4.DOM中创建节点的方法

创建元素节点
document.createElement(' ')

创建文本节点
document.createTextNode(' ')

创建注释节点
document.createComment(' ')

创建文档碎片节点

document.createDocumentFragment('')


5.DOM中插入节点

ParentNode.appendChild()

首先要有选择一个父节点,小括号里填写要插入的节点,会把节点插入到父节点的最后一位

一个节点只能插入到一个地方,再次插入这个节点之前插入的就会消失

ParentNode.insertBefore(a,b) 

在一个父节点内,把a节点插入到已知的b节点前面。

不一定非要插入自己创建的节点,已知的节点也可以使用插入调换位置


6.DOM中删除节点

ParentNode.removeChild()

父节点删除掉自己的节点并返回出去。

DOM入门篇_第9张图片

Child.remove()

直接销毁自身节点,连同自身的子节点一起删除。

返回undefined。

Node.replaceChild(new, origin)

替换一个节点,第一个填写新节点(new),第二个填写源节点(origin)(要替换的节点)。


7.元素(Element)节点的属性

innerHTML

可以查看,添加,覆盖HTML中的数据,

例如:



文字

控制台测试:

DOM入门篇_第10张图片

分别是对数据的查看,修改,覆盖。

如果添加的是元素节点的话,浏览器也会正常解释执行。


innerText(老版本火狐不兼容)  &&  textContent(老版本IE不支持

直接取出元素中的文本元素,赋值的话也可以覆盖源内容。



文字

121

执行  div.innerText  或者  div.textContent

输出:‘’文字    123‘’


8.元素(Element)节点的方法

Element.setAttribute

给一个元素节点设置属性(设置的新属性将会覆盖原来的属性

例如:



文字

121

此时的  div  有两个属性,id为demo, class为test。

Element.getAttribute

获取元素节点的属性值。



结合博客园观看

小总结:

  1、获取dom节点常用的方法:

    getElementById('idName'); 只能id用

    getElementsByTagName(''); 都能用,无兼容

    getElementsByClassName(''); 都能用, IE8及以下不兼容 

  2、document.body  => body

    document.head => head

    document.documentElement => html


以上内容的简单实践:

 1、模仿实现chldren方法  

复制代码
//重写children 
    Element.prototype.retChild = function(){
        var child = this.childNodes,
            len = child.length,
            obj = {
                'length' : 0,
                'push' : Array.prototype.push
            }
            for(var i = 0; i < len; i++ ) {
                if(child[i].nodeType == 1){
                    obj.push(child[i]);
                }
            }
            return obj;
    }
复制代码

 

  

复制代码
Element.prototype.retChildren = function(){
            var arrObj = {
                length: 0,
                push: Array.prototype.push
            } 
            
            for(var node = this.firstChild; node; node = node.nextSibling){
                if(node.nodeType == 1){
                    arrObj.push(node);
                }
            }
            return arrObj;
        }
复制代码

 

  2、封装函数,返回元素e的第n层祖先元素节点

复制代码
 Element.prototype.findIndexParent = function (n){
          var ret = this.parentNode? this.parentNode : this;
          while(--n) {
              if(!ret.parentNode) {
                  return ret;
              }
              ret = ret.parentNode; 
          }
          return ret;
      }
复制代码

 

  3、封装函数,返回元素e的第n个兄弟节点,n为正,返回后面的兄弟节点,n为负,返回前面的,n为0,返回自己

复制代码
 //    封装函数,返回元素e的第n个兄弟节点,n为正,返回后面的兄弟节点,n为负,返回前面的,n为0,返回自己
       Element.prototype.retIndexSibling = function (n) {
           var ret = this;
        //    n === 0
           if(n === 0) {
               return this;
           }
        //     n !=== 0
            while(n) {
               ret = n > 0? ret.nextSibling : ret.previousSibling;
            //    没有n个兄弟元素节点,则返回本身
               if(!ret) {
                   return this;
               }
               ret.nodeType === 1 && n > 0 && n--;
               ret.nodeType === 1 && n < 0 && n++;               
            }
            return ret;
       }
复制代码

 

  4、请编写一段JavaScript脚本生成下面这段DOM结构。要求:使用标准的DOM方法或属性。提示 dom.className 可以读写class

    


       

text


    

复制代码
//    创建div标签 且添加属性
       var oDiv = document.createElement('div');
       oDiv.className = 'example';
    // 创建p标签 且添加属性 填充内容
       var oP = document.createElement('p');
       oP.className = 'slogan';
       oP.innerHTML = 'text';
    // 按顺序插入
       oDiv.appendChild(oP);
       document.body.appendChild(oDiv);
复制代码

 

  5、封装函数insertAfter();功能类似insertBefore();提示:可忽略老版本浏览器,直接在Element.prototype上编程

  

复制代码
    //封装insertAfter()
        Element.prototype.insertAfter = function(targetNode, afterNode){
            var nextSib = afterNode.nextElementSibling;
      //如果父节点没有子元素或afterNode不存在的容错处理
if(this.children.length <= 1 || !nextSib){ this.appendChild(afterNode); }else { this.insertBefore(targetNode, nextSib); } }
复制代码

 

  6、封装remove(); 使得child.remove()直接可以销毁自身

Element.prototype.remove = function (){
        //   像那些属性节点,注释节点,文本节点等等根本不可能做父节点,所以可以说parentNode返回的一般都是父元素节点
            var definedParent = this.parentNode;
            definedParent.removeChild(this);
        }

 

  7、将目标节点内部的节点顺序逆序。
    eg:

复制代码
//    将所有子元素逆序
       Element.prototype.reverseChildren = function () {
           var children = this.children;
           var len = children.length;
           for(var i = 0; i < len; i++) {
               this.insertBefore(children[i], children[len - i - 1]);
               this.insertBefore(children[len - i - 1], children[i]);
           }
       }
复制代码

 

  8、parentElement 返回父级 元素节点(IE不兼容),  个人直接用node.parentNode就可以了,感觉除了元素节点外,其他类型节点都不适合做父节点

  9、childElementCount (IE不兼容),  我们直接用node.children.length代替他即可解决不兼容问题

  10、firstElementChild 返回第一个子级 元素节点(IE不兼容),我们用node.children[0]即可

  11、lastElementChild 返回最后一个子级 元素节点(IE不兼容), 我们用直接返回node.dhildren的最后一个元素就可

  12、nextElementSibling 返回后一个兄弟 元素节点(IE不兼容),js封装

  

    //  返回后一个兄弟 元素节点
       Element.prototype.nextEleSibling = function () {
        //    利用for循环的赋初值, 判断, 调整, 循环 这四种特性
           for(var ret = this.nextSibling; ret && ret.nodeType !== 1; ret = ret.nextSibling) {}
           return ret;
       }

  13、previousElementSibling 返回前一个兄弟 元素节点(IE不兼容), js封装, 原理同上

//  返回前一个兄弟 元素节点
       Element.prototype.nextEleSibling = function () {
        //    利用for循环的赋初值, 判断, 调整, 循环 这四种特性
           for(var ret = this.previousSibling; ret && ret.nodeType !== 1; ret = ret.previousSibling) {}
           return ret;
       }

你可能感兴趣的:(Javascript)