Javascript 找出两个dom元素的差异,然后使它们相同

Javascript 找出两个dom元素的差异,然后使它们相同,javascript,html,dom,Javascript,Html,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> <div id="myID"> <div id="

如果我有两个要素:

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

解决办法并不是那么简单。如果样本A中不存在父节点myID,但两个样本中都有子节点,表示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



在这种情况下,比较变得更加复杂。实际上,您将需要一个具有合并功能的完全充实的XML/HTML语言感知差异实用程序。您可以使用来演示这会变得多么复杂,但不幸的是,它没有合并功能,因此它不能完全自动解决您的问题。

因此,您可以对其进行优化,但这还取决于您在哪个浏览器中运行此代码。 我假设如下:

  • 所有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

  }
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有几种方法可以做到这一点,但是为了提供一种优化的方法,我们应该知道一些其他的细节:A)除了示例之外,孩子们可以只在结尾,还是在中间?孩子们总是有身份证吗?也可以说新元素的子元素少了吗?@ZER0你好,对于a)子元素可以在任何位置,不完全一样的问题;b) 是的,孩子们总是有身份证。你总是插入/删除孩子们吗?或者您有时需要添加/删除更深的子体吗?是的,有时我需要添加/删除更深的子体
<div id="papa">
    <div id="a"></div>
    <div id="b">
        <div id="ba"></div>
    </div>
    <div id="c">
        <span id="ca"></span>
    </div>
</div>
  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

  }