Skip to content

DomDiff状态机归纳

Army edited this page May 3, 2018 · 6 revisions

前置依赖

  • 空数组、null、undefined均视为空字符串。
  • vd被添加至真实dom后,遍历检测所有空字符串,为其创建内容为空的TextNode,保证节点对应(vd对应一个Dom,连续的text对应一个TextNode)。

基础部分

没有增删,只有更改的diff。

节点自身有2种状态:Text和Dom,变化引申出4种状态T2T、D2D、D2T、T2D。
状态机只看当前(之前结束后)状态,并根据自身变化决定下一状态,因此此时有16种(4*4)状态,之前的4种和本身4种。
first指vd的第一个孩子节点,index指vd的索引,start指真实Dom索引。

TT2TT

  • 第一个first,记录record的index为0,start为0。
  • 检查两个T2T内容是否变化,如是,记录刚才的record,进行textContent更新。

TT2TD

  • first记录record。
  • 检查T2T内容是否变化,如是,记录刚才的record,进行textContent更新。
  • T2D由于之前是T2T,之前的Text内容可能发生变更,记录刚才的record,进行textContent更新。
  • 处理T2D,start++为1,插入Dom,start++为2(为方便逻辑处理,start始终停留在Text上,遇到Dom跳到其之后)。

TT2DT

  • 记录record。
  • 处理T2D,替换start的Text为Dom,start++为1。
  • T2T由于之前为T2D,Text内容可能发生变更,记录刚才的record,进行textContent更新。

TD2TT

  • first记录record。
  • 检查T2T内容是否变化,如是,记录刚才的record,进行textContent更新。
  • D2T由于之前是T2T,之前的Text内容可能发生变更,记录刚才的record,进行textContent更新。
  • 处理D2T,移除start+1的Dom。

DT2TT

  • 处理D2T,替换start的Dom为Text,first记录record的index为0,start为0。
  • T2T由于之前是D2T,移除start+1的Text。
  • 记录刚才的record,进行textContent更新。

TT2DD

  • first记录record。
  • 处理T2D,替换start的Text为Dom,start++为1。
  • 再次T2D,由于之前也是T2D,插入Dom,start++为2。

TD2DT

  • first记录record。
  • 处理T2D,替换start的Text为Dom,start++为1。
  • 处理D2T,由于之前是T2D,替换start的Dom为Text,记录刚才的record。

DD2TT

  • 处理D2T,替换start的Dom为Text,first记录record的index为0,start为0。
  • 再次处理D2T,由于之前是D2T,删除start+1的Dom。
  • 记录刚才的record,进行textContent更新。

TD2TD

  • first记录record。
  • 检查T2T是否有变化,记录刚才的record,进行textContent更新。
  • 处理D2D,start++为1,替换start的Dom为新Dom,start++为2。

DT2TD

  • 处理D2T,替换start的Dom为Text,first记录record的index为0,start为0。
  • 处理T2D,由于之前是D2T,start++为1,替换start的Text为Dom,start++为2。

DT2DT

  • 处理D2D,替换start的Dom为新Dom,start++为1。
  • 检查T2T是否有变化,记录刚才的record,进行textContent更新。

DD2TT

  • 处理D2T,替换start的Dom为Text,first记录record的index为0,start为0。
  • 处理D2T,由于之前为D2T,删除start+1,记录刚才的record,进行textContent更新。

TD2DD

  • first记录record。
  • 处理T2D,替换start的Text为Dom,start++为1。
  • 处理D2D,替换start的Dom为新Dom,start++为2。

DT2DD

  • 处理D2D,替换start的Dom为新Dom,start++为1。
  • 处理T2D,由于之前是D2T,替换start的Text为Dom,start++为2。

DD2TD

  • 处理D2T,替换start的Dom为Text,first记录record的index为0,start为0。
  • 处理D2D,由于之前是D2T,start++为1,替换start的Dom为新Dom,start++为2。

DD2DT

  • 处理D2D,替换start的Dom为新Dom,start++为1。
  • 处理D2T,由于之前为D2T,替换start的Dom为Text,记录刚才的record。

扩展部分

没有更改,只有增删。

高级部分

增删改混合的情况。