亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript基礎修煉(10)——VirtualDOM和基本DFS

發布時間:2020-07-17 18:49:18 來源:網絡 閱讀:346 作者:大史不說話 欄目:web開發

javascript基礎修煉(10)——VirtualDOM和基本DFS

1. Virtual-DOM是什么

Virtual-DOM,即虛擬DOM樹。瀏覽器在解析文件時,會將html文檔轉換為document對象,在瀏覽器環境中運行的腳本文件都可以獲取到它,通過操作document對象暴露的接口可以直接操作頁面上的DOM節點。但是DOM讀寫是非常耗性能的,很容易觸發不必要的重繪和重排,為了更好地處理DOM操作,Virtual-DOM技術就誕生了。Virtual-DOM就是在javascript中模擬真實DOM的結構,通過數據追蹤和狀態對比來減少對于真實DOM的操作,以此來提高程序的效率的一種技術。

Virtual-DOM技術是前端高性能的基石,它是真實document對象的抽象,通過對比新舊Virtual-DOM的區別,找出發生變化的DOM節點,再利用算法得到相對更合理的DOM節點修改方案,最終再將方案應用在document對象上來改變頁面的展示內容。

主流前端SPA框架都離不開【Virtual-DOM模型 + DOM-Diff算法 + 生命周期鉤子】這樣的核心模型。

2. Virtual-DOM的基本結構

在上一篇博文《javascript基礎修煉(9)——MVVM中雙向數據綁定的基本原理》中,我們通過document.getElementById()從真實DOM中獲得了帶有自定義屬性的待解析結構,這里是有一些問題的,實際的過程是先解析模板字符串得到虛擬DOM樹,最后生成真實的DOM樹。

實際上我們在使用SPA框架時所編寫的html模板,并沒有被直接當做DOM片段加載到頁面上使用,而是將文件當做字符串讀入到程序中,然后通過解析來生成Virtual-DOM樹,接著通過SPA框架的渲染函數來生成必要的片段后才生成真實的DOM節點。例如我們要生成下文示例的HTML片段(為了方便演示,示例中只涉及了類名和文本節點):

<body class="main">
   <div class="sideBar">
       <ul class="sideBarContainer">
           <li class="sideBarItem">sidebar-1</li>
           <li class="sideBarItem">sidebar-2</li>
           <li class="sideBarItem">sidebar-3</li>
       </ul>
   </div>
   <div class="mainContent">
        <div class="header">header-zone</div>
        <div class="coreContent">core-content</div>
        <div class="footer">footer-zone</div>
   </div>
   <div class="rightSide">暫未開發</div>
</body>

我們需要構建出一個簡易模型來表達上面的結構:

virtualDom = {
    name:"body",
    props:{
        className:"main"
    },
    children:[{
        name:"div",
        props:{...},
        children:[...]
      },{
        name:"div",
        props:{...},
        children:[...]
      },{
        name:"div",
        props:{...},
        children:[...]
      }]
}

建立一個生成虛擬節點的輔助函數:

//構建DOM節點的輔助函數
function h(name, props, children) {
    return {
        name:name,
        props:props,
        children:children
    }
}
//手動生成virtual-DOM
var tree = h('body',{className:'main'},[
       h('div',{className:'sideBar'},[
          h('ul',{className:'sideBarContainer'},[
               h('li',{className:'sideBarItem'},['sidebar-1']),
               h('li',{className:'sideBarItem'},['sidebar-2']),
               h('li',{className:'sideBarItem'},['sidebar-3']),
            ])
        ]),
       h('div',{className:'mainContent'},[
           h('div',{className:'header'},['header-zone']),
           h('div',{className:'coreContent'},['core-content']),
           h('div',{className:'footer'},['footer-zone']),
        ]),
       h('div',{className:'rightSide'},['暫未開發'])
    ]);

通過上面的方法得到的tree對象就涵蓋了模板片段中的結構和關鍵信息。實際開發中并不需要像上面一樣手動來填寫DOM結構,可以將模板字符串掛載到離線DOM節點上,然后在遞歸解析的同時來構建Virtual-DOM就可以了。

3. 使用DFS從Virtual-DOM生成DOM

至此我們完成了模板的編譯,也得到了Virtual-DOM對象,但它似乎并沒有什么用處,畢竟我們已經完成了對模板的解析,渲染出頁面沒什么問題,其實Virtual-DOM對于首屏來說并沒有什么特別重要的意義,它的價值在模型和視圖發生變化時才會體現。上一篇博文的末尾我們已經提到了更新視圖時的效率問題,當數據模型發生變化后,我們需要一個方法來收集所有需要修改的DOM,并為之提供高效的修改方式(你總不能一有變化就把整個網頁重新渲染,或者讓數據模型各自去修改各自綁定的DOM吧)。那么為了能夠收集所有DOM節點的變化,我們就需要遍歷所有節點。

對數據結構和算法有一定了解的讀者很容易想到,遍歷解析一個Virtual-DOM實際上就是對其進行先序深度優先遍歷(Pre-Order Depth-First-Search),本節中,我們先預熱一下,使用這種方式來復現一下DOM結構。

function dfswalking(tree) {
    var _childrenLength;
    //執行動作
    if (typeof tree.children[0] === 'string') {
        console.log(`<${tree.name} class="${tree.props.className}">${tree.children[0]}</${tree.name}>`);
    } else {
        console.log(`<${tree.name} class="${tree.props.className}">  -->`);
        for(var i = 0, _childrenLength = tree.children.length; i < _childrenLength; i++){
            dfswalking(tree.children[i]);
        }
    }
}

本例中僅打印出字符串的方式來展示,可以在控制臺看到輸出結果:

javascript基礎修煉(10)——VirtualDOM和基本DFS

下一篇博文中將分析如何通過domDiff(oldTree, newTree)的方法通過同樣的遍歷方法來收集變化并批量更新視圖。

4. 聲明

本篇只是部分原理的學習筆記,并不代表框架真實源碼的實現邏輯。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

盐津县| 江北区| 准格尔旗| 江安县| 望城县| 广宁县| 常宁市| 扎兰屯市| 黎平县| 麻城市| 图木舒克市| 九龙坡区| 集安市| 确山县| 晋宁县| 陕西省| 兰州市| 明水县| 平舆县| 会泽县| 浦北县| 柳州市| 武汉市| 西丰县| 浦江县| 敖汉旗| 锡林郭勒盟| 齐河县| 建宁县| 舟山市| 正宁县| 九龙坡区| 黄浦区| 保定市| 浦北县| 二连浩特市| 虹口区| 阳谷县| 阿瓦提县| 始兴县| 德钦县|