3

2つの要素がある場合:

要素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追加の要素がどこにあるかを見つけて、それを作成することは可能Element Aですか?

PS:実際のコードでは、新しい要素がロードされますがAjax Request、すべてのコンテンツをロードされたコンテンツに置き換えたくないので、新しいコンテンツのみを追加し、既存のコンテンツをスキップする必要があります。

PSS:現在のコードでは、新しいコンテンツが既存のものと同じでないかどうかを確認する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)};
      }
    }
  };
4

2 に答える 2

1

したがって、最適化することはできますが、このコードを実行しているブラウザによっても異なります。私は次のように仮定しました:

  • すべてのIDは一意であり、それに依存します。基本的に、同じ構造ではなく、同じ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

  }
于 2012-07-14T11:51:51.537 に答える
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言語対応のdiffユーティリティが必要になります。Pretty Diffをいじって、これがどれほど複雑になるかを示すことができますが、残念ながら、マージ機能がないため、問題の完全に自動化されたソリューションにはなりません。

于 2012-07-14T11:40:58.950 に答える