長沙IT培訓程序員面試題:DOM DIFF
在程序員的職業生涯中,無論是在跳槽時還是晉升時都會遇到各式各樣的面試,那么就技術層面上而言,這篇長沙IT培訓程序員面試題:DOM DIFF希望能給你幫助。
通過JS層面的計算(逐層比對虛擬DOM對象),生成patch對象(即補丁對象),然后對補丁進行解析和重新渲染
對樹進行分層比較,兩棵樹只會對同一層次的節點進行比較(不會跨節點比較)
React 只會簡單的考慮同層級節點的位置變換,而對于不同層級的節點,只有創建和刪除操作
可以處理同級節點順序的改變每一層級進行對比的計算法則:深度優先遍歷節點類型相同,看屬性是否相同,如果不同,則產生屬性的補丁包 {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
更多>>熱門推薦
參加完長沙Java培訓班之后怎么面試找工作?
沸參加長沙IT培訓好找工作嗎?這些環節能刷掉70%大學生
熱參加長沙Java培訓跳槽去大廠,都有哪些面試要求?
熱千鋒長沙前端培訓分享之高級前端面試題整理
新千鋒長沙前端培訓分享之中級前端面試題整理
千鋒長沙前端培訓分享之初級前端面試題整理
千鋒長沙前端培訓:Vue相關面試題
長沙Java培訓:高并發編程JUC包面試題及答案
長沙Java培訓:Java開發實用的面試題及答案
長沙Java培訓:2021年Java面試題分享
長沙Java培訓:2021Java面試題分享
長沙千鋒整理:軟件測試中頻率最高的網絡協議面試題,收好了!
長沙IT培訓學員整理:程序員面試10條潛規則
自學前端靠這份面試題和答案,也能拿高薪!