zoukankan      html  css  js  c++  java
  • 将真实DOM转换为虚拟DOM

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        
    </style>
    </head>
    <body>
    
        <div id="root" class="tt">
            <div title="tt1">hello1</div>
            <div title="tt2">hello2</div>
            <div title="tt3">hello3</div>
            <ul>
                <li>1</li>
                <li>2</li>
                <li>3</li>
            </ul>
        </div>
    
    
    <script>
        // 用内存去表述DOM
        // 将真实DOM转化为虚拟DOM
        // <div />  => {tag:'div'}   元素转化
        // 文本节点 => {tag:undefined,value:'文本节点'}   文本节点转化
        // <div title="1" class="c"  />  => { tag:'div',data:{ title:'1',class:"c" } }   多属性转化
        // <div><div /></div> => {tag:'div',children:[{ tag:'div' }]} 
    
        // 用构造函数来 进行以上转换
        // 这一次我们用class语法
    
        class VNode {
            // 构造函数
            constructor( tag,data,value,type ){
                // tag:用来表述 标签  data:用来描述属性  value:用来描述文本 type:用来描述类型
                this.tag = tag && tag.toLowerCase();//文本节点时 tagName是undefined
                this.data = data;
                this.value = value;
                this.type = type;
                this.children = [];
    
            }
            appendChild( vnode ){
                this.children.push( vnode );
            }
        }
        /**
        利用递归 来遍历DOM元素 生成虚拟DOM
        Vue中的源码使用 栈结构  ,使用栈存储 父元素来实现递归生成
        */
        function getVNode( node ){
            let nodeType = node.nodeType;
            let _vnode = null;
    
            if( nodeType === 1){
                // 元素
                let nodeName = node.nodeName;//元素名
                let attrs = node.attributes;//属性  伪数组
                let _attrObj = {};
                for(let i=0;i<attrs.length;i++){//attrs[ i ] 属性节点(nodeType == 2) 是对象
                    _attrObj[ attrs[ i ].nodeName ] = attrs[ i ].nodeValue;
                }
                _vnode = new VNode( nodeName,_attrObj,undefined,nodeType);
                // 考虑node的子元素
                let childNodes = node.childNodes;
                for(let i = 0;i<childNodes.length;i++){
                    _vnode.appendChild( getVNode( childNodes[ i ] ) );//递归
                }
            }else if(  nodeType === 3 ){
                // 文本节点
                _vnode = new VNode( undefined,undefined,node.nodeValue,nodeType);
            }
            return _vnode;
        }
    
        let root = document.querySelector("#root");
    
        let vroot = getVNode ( root );
        console.log(vroot);
    
    
    
    </script>
    
        
    </body>
    </html>

  • 相关阅读:
    向量求导几则公式备忘
    电脑硬件接触不良
    caffe编译新问题
    faster-rcnn 目标检测 数据集制作
    py-faster-rcnn 的makefile.config 注意事项
    ubuntu14.04 python + opencv 傻瓜式安装解决方案
    轻量级神经网络平台tiny-dnn实践
    OpenMP 并行编程
    React在Render中使用bind可能导致的问题
    为了cider,尝试emacs的坑
  • 原文地址:https://www.cnblogs.com/fqh123/p/13623260.html
Copyright © 2011-2022 走看看