DOM && 虚拟 DOM

1,032 阅读3分钟

1.DOM 是什么

dom 是document object model 文档对象模型的简写,其中定义了访问和操作html、xml文档的标准,他允许程序动态的更改文档的内容、结构、样式,下面我们只针对学习html dom的学习。

2.HTML DOM

我们之前学习很多数据结构,比如栈、队列、链表、集合、字典(object)、散列、树、图;现在我们将要学习的html dom 就是一个树结构的数据类型;如下图

  • 节点之间存在parentNode(父节点,根节点除外)、childNodes(子节点)、sbiling(兄弟节点)的关系,如下图

  • 每个节点都是一个对象,既然是对象,1.对象就存在方法和属性,接下来的操作dom就是依赖相关的方法和属性进行操作,2.对象就会存在原型,那一个节点的原型是怎么样的呐,我们可以console.dir(node)节点查看node对象原型链,你会发现出现六层的_proto_原型对象,结构如下图

  • 特别是第五层的Eventarget的原型中包含addEventListener()方法,是不是就是我们平时给元素节点添加事件监听操作的api,由于该pai在node节点中包含,所以可以继承操作该方法

3.操作HTML DOM

html dom 都是一个个对象,所以我们可以利用相关的属性和方法进行dom操作,也就是对dom的增删改查操作,还有一个知识点就是,dom节点包含元素节点和文本节点,我们可以通过node.nodeType来辨别,

  • 获取特定的元素:
  1. document文档root, 
  2. doument.doumentElement:html元素,
  3. doument.body:body元素,
  4. doument.head:head元素,
  5. document.all:获取所有元素
  6. node.childNodes 所有子节点
  7. node.children 所有元素节点
  8. node.parentNode 父节点
  9. node.parentElement 父元素
  10. node.previousSibling 前一个兄弟节点
  11. node.previousElemnetSibling 前一个兄弟元素
  12. node.nextSibling 后一个元素节点
  13. ...
  • 查找一个节点api:
  1. document.getElementById() :通过id查找dom
  2. document.getElementsByTagName():通过元素标签查找
  3. document.getElementsByClassName():通过类名查找
  4. document.getElementsByName(),通过函数name属性的元素
  5. docmenet.querySelectorI('#id'):通过写css方式获取元素
  6. document.querySelectorAll():查找一类符合条件的元素
  • 增加一个节点
  1. 创建一个元素节点:document.createELement()
  2. 创建一个文本节点:document.createTextNode()
  3. 然后插入相应的节点中:node.appendChild(),document.append()这个默认在元素的尾部拆入节点,如果需要前面插入节点就需要使用box..insertBefore(div,div1),即在box节点的第一div1节点前面插入
  4. 属性innerHtml、innerText也可以添加相应的元素和节点
  • 删除一个节点
  1. parentNode.removeChild(node),parentNode.romve(node)
  • 更改一个节点
  1. 修改class:node.classList.add()、node.className = ''(编程时候推荐操作类的方式进行dom编程)
  2. 修改style:node.style.color = ''
  3. 修改内容:node.innerText = ''
  4. 修改属性:node.setAtrribute(),node.getAtrribute()
  5. 修改事件处理函数:node.onclick = function(){}

3.vue、react 中的虚拟dom

3.1 定义:能够表示dom的对象,对象中含有标签名、属性、子节点、事件监听等

3.2 dom结构

  • react 中的虚拟dom 数据结构如下代码

  •   const vNode = {
       key:xxx,
       type:'div',
       ref:xxx
       prop:{
        className:xxx,
        onClick:()=>{}
        children:[
          {type:p,....},
          {type:span,...}
        ]
       }
      }
    
  • vue 中的虚拟dom数据结构如下代码

  •   const vNode = {
          tag:'div',
          data:{
          class:'red',
          on:{
           click(){}
          }
         },
          children:[
          {tag:p,....},
          {tag:span,...}
          ]
      }
    

3.3 怎么创建虚拟dom

  • vue 通过h函数

    h('div',{ class:'red', on:{ click:()=>{} }},[h('p',{},'span'),h('p',{},'span')])

  • react 通过createElement()函数

    createElement('div',{ className:'red, onClick:()=>{}, [ createElement('p',{//属性},'span'), createElement('p',{//属性},'sapn') ] })

3.4虚拟dom的好处

  • 减少dom操作次数,虚拟dom将需要创建的元素存放在数组中,之后再一次性的插入到节点,同时借助dom diff 一层层比较dom变化来得到patch再更新dom;
  • 跨平台支持