Visual DOM diff演算法實現

2021-08-05 22:38:32 字數 3282 閱讀 6809

使用document.createelement 和 document.createtextnode建立的就是真實節點。

比較只會在同層級進行, 不會跨層級比較。

div>我們可能期望將直接移動到

的後邊,這是最優的操作。但是實際的diff操作是移除

裡的在建立乙個新的插到

的後邊。因為新加的在層級2,舊的在層級3,屬於不同層級的比較。

diff的過程就是呼叫patch函式,就像打補丁一樣修改真實dom。

//vnode和oldvnode,也就是新舊兩個虛擬節點

function

patch

(oldvnode, vnode) else

}return vnode

}

// body下的  對應的 oldvnode 就是

el=div, //對真實的節點的引用,本例中就是document.queryselector('#id.classa')

tagname='div',//節點的標籤

sel='div#v.classa'

//節點的選擇器

data=null

// 乙個儲存節點屬性的物件,對應節點的el[prop]屬性,例如onclick , style

chilren=//儲存子節點的陣列,每個子節點也是vnode結構

text=null, //如果是文字節點,對應文字節點的textcontent,否則為null

// el屬性引用的是此 virtual dom對應的真實dom,patch的vnode引數的el最初是null,因為patch之前它還沒有對應的真實dom。

function

patch

(oldvnode, vnode) else

}return vnode

}function

samevnode

(oldvnode, vnode)

//兩個節點值得比較時,會呼叫patchvnode函式

function

patchvnode

(oldvnode, vnode)else else

if (ch)else

if (oldch)

}}function

updatechildren

(parentelm, oldch, newch) else

if (oldendvnode == null) else

if (newstartvnode == null) else

if (newendvnode == null) else

if (samevnode(oldstartvnode, newstartvnode)) else

if (samevnode(oldendvnode, newendvnode)) else

if (samevnode(oldstartvnode, newendvnode)) else

if (samevnode(oldendvnode, newstartvnode)) else

idxinold = oldkeytoidx[newstartvnode.key]

if (!idxinold)

else else

newstartvnode = newch[++newstartidx]}}

}if (oldstartidx > oldendidx) else

if (newstartidx > newendidx)

}

源**

import  from '../util/index'

import from './index'

function

samevnode

(oldvnode, vnode)

function

createkeytooldidx

(children, beginidx, endidx) , key, ch

for (i = beginidx; i <= endidx; ++i)

}return map

}function

removevnodes

(parentelm, vnodes, startidx, endidx) }}

function

addvnodes

(parentelm, before, vnodes, startidx, endidx)

}}

function

patchvnode

(oldvnode, vnode) else else

if (ch)else

if (oldch)

}}function

updatechildren

(parentelm, oldch, newch) else

if (oldendvnode == null) else

if (newstartvnode == null) else

if (newendvnode == null) else

if (samevnode(oldstartvnode, newstartvnode)) else

if (samevnode(oldendvnode, newendvnode)) else

if (samevnode(oldstartvnode, newendvnode)) else

if (samevnode(oldendvnode, newstartvnode)) else

idxinold = oldkeytoidx[newstartvnode.key]

if (!idxinold)

else else

newstartvnode = newch[++newstartidx]}}

}if (oldstartidx > oldendidx) else

if (newstartidx > newendidx)

}export function

patch

(oldvnode, vnode) else

}return vnode

}

演算法基礎( 演算法)

演算法基礎 演算法 hash演算法有兩種,即sha 1和md5演算法這裡先介紹md5演算法.md5產生乙個128位的hash值,在經過一寫初始樹立後,將明文分成了512位的塊,再將每一塊分成16個32位的子塊。演算法的輸出是4個32位的塊,連線起來構成128位的hash值。首先,將訊息填充到比512...

演算法 分治演算法

分治策略主要利用遞迴來解決問題,它包括以下三個步驟 分解 將問題分解為一與原問題類似並且比原問題規模更小的子問題 解決 當分解的子問題足夠小時,直接給出答案,否則用遞迴打方式求解 合併 將子問題的解合成原問題的解 下面考慮乙個簡單的利用分治演算法的歸併排序的例子 問題的形式化描述如下 輸入 a是 乙...

演算法 遞迴演算法

遞迴演算法的概念,就是通過不斷地呼叫自身,最終達到解決問題的目的。遞迴有兩個點需要注意 1.要不斷的呼叫自身 2.這個遞迴要有出口,不能成為死迴圈 看下面的例子。很多介紹遞迴演算法的,都會用遞迴來做乙個題目 計算乙個數的階層。例如 計算5的階層,5 5 x 4 x 3 x 2 x 1 用遞迴來實現 ...