<option id="mwy0y"><strong id="mwy0y"></strong></option>
  • <ul id="mwy0y"><sup id="mwy0y"></sup></ul>
  • <ul id="mwy0y"></ul>
  • <del id="mwy0y"><dfn id="mwy0y"></dfn></del><ul id="mwy0y"><sup id="mwy0y"></sup></ul>
  • <abbr id="mwy0y"></abbr>

    千鋒教育-做有情懷、有良心、有品質的職業教育機構

    400-811-9990
    手機站
    千鋒教育

    千鋒學習站 | 隨時隨地免費學

    千鋒教育

    掃一掃進入千鋒手機站

    領取全套視頻
    千鋒教育

    關注千鋒學習站小程序
    隨時隨地免費學習課程

    上海
    • 北京
    • 鄭州
    • 武漢
    • 成都
    • 西安
    • 沈陽
    • 廣州
    • 南京
    • 深圳
    • 大連
    • 青島
    • 杭州
    • 重慶
    當前位置:長沙千鋒IT培訓  >  面試技巧  >  長沙IT培訓程序員面試題:DOM DIFF

    長沙IT培訓程序員面試題:DOM DIFF

    來源:千鋒教育
    發布人:千鋒長沙
    時間: 2021-03-19 16:19:00

            在程序員的職業生涯中,無論是在跳槽時還是晉升時都會遇到各式各樣的面試,那么就技術層面上而言,這篇長沙IT培訓程序員面試題:DOM DIFF希望能給你幫助。

            通過JS層面的計算(逐層比對虛擬DOM對象),生成patch對象(即補丁對象),然后對補丁進行解析和重新渲染

            對樹進行分層比較,兩棵樹只會對同一層次的節點進行比較(不會跨節點比較)

    4.png

            React 只會簡單的考慮同層級節點的位置變換,而對于不同層級的節點,只有創建和刪除操作

    4.png

            可以處理同級節點順序的改變每一層級進行對比的計算法則:深度優先遍歷節點類型相同,看屬性是否相同,如果不同,則產生屬性的補丁包 {type:’ATTRS’,attrs:{class:’BB’}}新的DOM節點不存在,被刪除了{type:’REMOVE’,index:xxx}節點類型不相同,直接替換即可 {type:’REPLACE’,newNode:xxx}文本的內容進行變化 {type:’TEXT’,text:xxx}

            function diff(oldTree,newTree){ let patchs = {}; //=>補丁包 按照層級放置補丁包 {1:[],2:[]} let index = 0; //=>比較的層級 //=>遞歸樹,比較后的結果放到補丁包 walk(oldTree,newTree,index,patchs); return patchs;}function walk(oldNode,newNode,index,patchs){ let currentPatch={}; if(!newNode){ //=>新元素不存在,代表刪除 currentPatch.push({ type:'EMOVE', index }); }else if(typeof oldNode==="string"&&typeof newNode==="string"){ //=>如果是文本,判斷文本是否改變 if(oldNode!==newNode){ currentPatch.push({ type:'TEXT', text:newNode }); } }else if(oldNode.type===newNode.type){ //=>比較屬性是否有更改 let attrs=diffAttr(oldNode.props,newNode.props);, if(Object.keys(attrs).length>0){ currentPatch.push({ type:'ATTRS', attrs }); } //=>如果有兒子節點,則遍歷兒子 diffChildren( oldNode.props.childrren, newNode.props.childrren, index,patchs); }else{ //=>節點被替換了 currentPatch.push({ type:'REPACE', newNode }); } //=>當前本級查找,確實有補丁,我們放到最外層補丁包中 if(currentPatch.length>0){ patchs[index]=currentPatch; }}//=>比較兒子function diffChildren(oldChildren,newChildren,index,patchs){ oldChildrren.forEach((child,ind)=>{ walk(child,newChildren[ind],++index,patchs); })} //=>比較屬性,生成補丁包function diffAttr(oldAttrs,newAttrs){ let patch={}; for(ley key in oldAttrs){ //=>屬性不一樣(可能是把老的中某個刪除了,這樣獲取的結果可能是undefined) if(oldAttrs[key]!==newAttrs[key]){ patch[key]=newAttrs[key]; } } for(ley key in newAttrs){ //=>看老的節點中是否有這樣一個屬性(沒有就是新增) if(!oldAttrs.hasOwnProperty(key)){ patch[key]=newAttrs[key]; } } return patch;}復制代碼根據補丁重新渲染let patchs=diff(xxx,xxx); //=>兩個虛擬DOMlet node;let index=0;walk(node);functon walk(node){ let currentPatch=patches[index++]; let cildNodes=node.childNodes; cildNodes.forEach(child=>walk(child)); if(currentPatch.length>0){ doPatch(node,currentPatch); }}function doPatch(node,patch){ patchs.forRach((item,index)=>{ switch(patch.type){ case 'ATTRS': for(let key in patch.attrs){ let val=patch.attrs[key]; if(val){ setAttr(node,key,val); }else{ node.removeAttribute(key) } } break; case 'TEXT': node.textContent=patch.text; break; case 'REPLACE': let newNode=(patch.newNode instanceof Element)?render(patch.newNode):document.createTextNode(patch.newNode); node.parentNode.replaceChild(newNode,node); break; case 'REMOVE': node.parentNode.removeChild(node); break; } }) }復制代碼總結通過JS層面計算 === 對比的是虛擬DOM對象第一次加載頁面,所有的內容都要重新渲染(語法解析 -> 虛擬DOM -> 真實DOM -> 瀏覽器渲染) =>第一次加載頁面越少渲染越好上一次計算出來的虛擬DOM對象會存儲起來,當狀態或者其它數據改變,重新渲染組件(重新生成一套虛擬DOM對象)把重新生成的虛擬DOM 和 之前存儲起來的虛擬 DOM進行對比=>把不一樣的以補丁的形式存儲起來(存儲的還是對象)重新渲染的過程,只是把補丁渲染到頁面中,原有渲染過但是沒有改變的東西是不需要處理的

            本套學習內容由千鋒長沙IT培訓班韋老師撰寫,版權歸千鋒教育學院所有,歡迎轉載,轉載請注明作者出處謝謝!

    聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。

    猜你喜歡LIKE

    最新文章NEW

    相關推薦HOT

    更多>>

    快速通道 更多>>

    最新開班信息 更多>>

    網友熱搜 更多>>