2012-07-14 54 views
3

如果我有兩個元素:覺得有兩個DOM元素的差異使他們同

元素A:

<div id="myID"> 
    <div id="a"></div> 
    <div id="b"><div id="ba"></div></div> 
    <div id="c"><span id="ca"></span></div> 
</div> 

元素B:

<div id="myID"> 
    <div id="a"></div> 
    <div id="b"><div id="ba"></div></div> 
    <div id="c"><span id="ca"></span></div> 
    <div id="d"></div> 
</div> 

是有可能發現Element B比有更多的孩子,然後找到附加元素在哪裏並在Element A中創建它?

P.S:在實際代碼中,新元素加載了Ajax Request,但我不想用加載內容替換所有內容,我只需添加新內容並跳過現有代碼。 P.S.S:在我當前的代碼中,我有Md5校驗和以檢查新內容是否與現有的內容不一樣,但是如果新內容只有很小的變化,它將替換所有內容,這對我來說是個問題。

一塊我當前的代碼:

window.processResponse = function(data) { 
    // Note : "data" is Ajax responseText; 
    if(!data) return false; 
    var $data = document.createElement("div"); 
    $data.innerHTML = data; 
    var em = $data.getElementsByTagName("*"); 
    for(var i = 0; i < em.length; i++) 
    { 
     var parent = sget(em[i].id); // sget function is : document.getElementById 
     if(parent) 
     { 
     var html = em[i].innerHTML.replace(/(\s)+/gim, "").replace(/(\n|\r\n)+/gim, ""); 
     var id = em[i].id; 
     savedPages[id] = savedPages[id] || []; 
     var _md5 = md5(html); 
     if(savedPages[id][0] == _md5) continue; 
     savedPages[id] = [_md5, getTime()]; 
     parent.innerHTML = em[i].innerHTML; 
     } 
     if(em[i].tagName === "SCRIPT") 
     { 
     var code = em[i].innerHTML.replace(/(\s)+/gim, "").replace(/(\n|\r\n)+/gim, ""); 
     var id = em[i].id; 
     savedPages[id] = savedPages[id] || []; 
     var _md5 = md5(code); 
     if(savedPages[id][0] == _md5) continue; 
     savedPages[id] = [_md5, getTime()]; 
     try{eval(em[i].innerHTML)}catch(ex){log(ex)}; 
     } 
    } 
    }; 
+0

有幾種方法你CA做到這一點,但爲了提供最優化的一個,我們應該知道其他一些細節:1)可除只在喜歡的例子,或也該結束了孩子中間?讓孩子們總是ID?也可以說新元素的孩子少了? – ZER0 2012-07-14 11:11:02

+0

@ ZER0你好,對於a)孩子可以處於任何位置,不完全像問題; b)是的,孩子們總是有身份證 – John 2012-07-14 11:13:30

+0

你是否總是插入/取出孩子?或者你是否需要有時添加/刪除更深的後代? – Chris 2012-07-14 11:53:34

回答

1

所以,你可以優化它,但它也取決於你運行這個代碼的瀏覽器。 我假設如下:

  • 所有ID都是唯一的,你依靠這一點。你想基本上比較具有相同ID的元素,而不是相同的結構。

  • 正如你所說的,所有的孩子都有標識,並希望獨生子女比較 - 沒有嵌套節點

  • 從服務器接收到的元素有唯一的額外孩子不能少。爲了刪除孩子,你必須添加一些其他的代碼。

  • 因此,如果您有相同數量的子女,我們假設他們是相同的(要優化)。如果這是不正確的,那麼你就必須實現去除兒童以及

說,我認爲,這些東西更適合在服務器端,應該發送到客戶端只有部分這實際上是修改的。我們通常所做的 - 或者,如果我們不在乎,就取代一切。

var div = document.createElement('div'); 
    div.innerHTML = s; 

    var root = div.firstChild; 
    var children = root.children; 

    var documentRoot = document.getElementById(root.id); 

    if (documentRoot && documentRoot.children.length < children.length) { 
    var node = null; 
    var previousNode = null; 
    var index = 0; 

    while (node = children[index++]) { 
     var documentNode = document.getElementById(node.id); 

     if (!documentNode) { 
     if (previousNode) 
      documentRoot.insertBefore(node, previousNode.nextSibling); 
     else 
      documentRoot.insertBefore(node, documentRoot.firstChild); 

     documentNode = node; 
     } 

     previousNode = documentNode; 

    } 

    previousNode = null; 

    } else { 
    // probably append as is somewhere 

    } 
0

的解決方案是不那麼簡單。如果父類myID在樣本A中不存在,但是這兩個樣本中的子節點都指示DOM中需要進行比較和調整的3個圖層?你如何比較這:

<div id="papa"> 
    <div id="myID"> 
     <div id="a"></div> 
     <div id="b"> 
      <div id="ba"></div> 
     </div> 
     <div id="c"> 
      <span id="ca"></span> 
     </div> 
    </div> 
</div> 

VS

<div id="papa"> 
    <div id="a"></div> 
    <div id="b"> 
     <div id="ba"></div> 
    </div> 
    <div id="c"> 
     <span id="ca"></span> 
    </div> 
</div> 

在這種情況下,比較就變得更加複雜了。實際上你需要一個充分充實的帶有合併功能的XML/HTML語言識別差異工具。你可以玩Pretty Diff來演示這可以得到多麼複雜,但不幸的是它沒有合併功能因此它不能是一個完全自動化的解決方案,以解決您的問題。