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>

  • 相关阅读:
    2.12 使用@DataProvider
    2.11 webdriver中使用 FileUtils ()
    Xcode8 添加PCH文件
    The app icon set "AppIcon" has an unassigned child告警
    Launch Image
    iOS App图标和启动画面尺寸
    iPhone屏幕尺寸、分辨率及适配
    Xcode下载失败 使用已购项目页面再试一次
    could not find developer disk image
    NSDate与 NSString 、long long类型的相互转化
  • 原文地址:https://www.cnblogs.com/fqh123/p/13623260.html
Copyright © 2011-2022 走看看