虚拟DOM渲染(用节点等方法将对象渲染到body中)

113 阅读1分钟
<script>


    /*

      将这个虚拟节点数据 具象化成实际标签

    */
    
 

//对象 中套了数组对象
    var element = {

      tagName: 'div',

      id: 'header',

      className: 'title fw400 c666 fz28',

      contentText: '我是一个header标签',

      children: [

        {

          tagName: 'h1',

          id: '',

          className: 'logo',

          contentText: '我是logo',

          children: []

        },

        {

          tagName: 'ul',

          id: '',

          className: 'nav',

          contentText: '',

          children: [

            {

              tagName: 'li',

              id: '',

              className: 'list',

              contentText: '导航1',

              children: []

            },

            {

              tagName: 'li',

              id: '',

              className: 'list',

              contentText: '导航2',

              children: []

            },

          ]

        }

      ]

    }

    //遍历对象

    /*

      1.确定自己要做什么

        创建节点对象

        设置对应属性

        添加到页面上

        重复上述过程对children下级元素

      2.根据列出的细化需求,

        1.var vDom = document.createElement(tagname)//vDom=>viewDom

        2.id=>id className=>className  innerText=>innerText

        3.parentElement.appendChild(vDom)

      3.将方法组合 修正 优化

        1.属性是一样的 创建和添加方法是一样的 属性设置是一样的

        //dom.property = value

        //property 只能是dom对象已有的自身属性 class id style title

        //dom.['property']也可以类似 对象

    */

  


    // //创建一个tagName是element['tagName']的元素节点

    // var oDom = document.createElement(element['tagName'])

    // //添加属性和内容

    // oDom.className = element['className']

    // oDom.innerText = element['contentText']

    // //添加节点

    // document.body.appendChild(oDom)

  
  


    //创建一个函数 传入对象和父级(在谁里边加)

    function drawElement(elementfn,parentfn){

      var oDom = document.createElement(elementfn['tagName'])

      //给contentText同名为 innerText

      elementfn['innerText'] = elementfn.contentText

      //遍历对象 添加属性值和文本内容

      for(var key in elementfn){

        //因为对象中键名 跟标签内的属性同名 所以可以直接

        //oDom[key] 但contentText 跟innerText不同命 所以给他同名一个 属于取巧了

        // oDom[key] = elementfn[key]

        //此处有个问题 null的id属性也会传进去

        //解决方法

  


        //方法一if判断一下

        // if(elementfn[key]){

        //   oDom[key] = elementfn[key]

        // }

  


        //第二种方法 把children排除

        if(key !== 'children'){

          //用逻辑运算符 &&左边为真输出右边 否则相反

          elementfn[key] && (oDom[key] = elementfn[key])

        }

       

      }

      //添加节点

      parentfn.appendChild(oDom)

  
  


      //如果对象中有数组

      if(elementfn['children'].length >0 ){

        //循环数组中的对象 传回drawElement

        for(var i = 0; i<elementfn['children'].length; i++){

          // console.log(i)

          // console.log(element['children'][i])

          //递归函数 自己调用自己

          drawElement(elementfn['children'][i],oDom)//传入两个参数 一个是对象 一个是需要父级

          //因为children 在tagName后续 每个对象中都有taName 所以父级就是每次函数声明的oDom

        }

      }

  
    }

  

    drawElement(element,document.body)

  </script>