3

如果我有两个元素:

元素 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>

对比

<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来演示这会变得多么复杂,但不幸的是它没有合并功能,因此它不能成为您问题的完全自动化解决方案。

于 2012-07-14T11:40:58.950 回答