无论孩子如何,检查父节点是否相等

时间:2017-10-10 04:08:43

标签: javascript html element

我正在寻找一种快速的方法来检查2个元素是否彼此相等,无论他们有什么孩子。 isEqualNode不起作用,因为它也比较了元素的子元素。

所以,在这个例子中,我想创建一个函数,如果给出2个<div class="foo" style="background-color: green;">元素作为参数,则返回true,即使它们有不同的子元素。

<div class="foo" style="background-color: green;">
  <h3>bar</h3>
  Hello
</div>

<div class="foo" style="background-color: green;">
  <div class="goat" />
</div>

<script>
  function checkIfParentNodesAreEqual(el1, el2) { /* magic */}

  var els = document.getElementsByClassName('foo');
  checkIfParentNodesAreEqual(els[0], els[1]) // I want this to return true
</script>

所以我想知道,如果这2个元素相等,那么在性能方面最好的方法是什么?

我知道我们可以对两个节点进行浅层克隆并比较克隆,或者我们可以删除所有子节点,比较父节点,然后重新附加子节点,但我想知道是否存在一种更快的方式。

3 个答案:

答案 0 :(得分:2)

您可以尝试克隆节点,删除子节点然后进行比较。 在我们制作克隆时,您不必重新附加孩子。

month

我希望这会有所帮助。

答案 1 :(得分:2)

您必须对节点进行浅层复制才能进行比较,如下所示:

function compareNodes (nodes, shallow) {
  if (shallow) nodes = nodes.map((node) => node.cloneNode(false))
  return nodes.every((node, index, nodes) => {
    let nextIndex = index + 1
    return nodes[nextIndex] ? node.isEqualNode(nodes[nextIndex]) : true
  })
}

compareNodes(Array.from(document.getElementsByClassName('foo')), true)

但正如您所说,您正在寻找可能更有效的替代方案。我不认为上面的实现效率非常低,但您必须自己专门针对您的应用程序进行测试,并了解它的执行情况。我能想到的一个替代方案是使用虚拟DOM并利用其差异算法,但它们也有其缺点 - 如this blog post over at Auth0中所述。您必须对此进行一些挖掘,以找出您要使用的实现。虽然我相信你会顺利完成上述实施。

更新我对上述实施进行了一些测试,比较了总共1,000个节点,包括对每个节点进行浅层复制,在我的系统上平均花费3毫秒。

答案 2 :(得分:0)

在某些时候,功能 isSameNode()已定义,但现在它被优先使用===运算符(triple =)来验证两个元素是否有用与行为相同的元素:

function checkIfParentNodesAreEqual(el1, el2) 
{ 
  /* magic */
  return( el1.parentElement === el2.parentElement );
}

如果您希望使用parentNode属性而不是parentElement,请查看HTML DOM parentElement Property

请查看HTML DOM isSameNode() Method了解有关比较的详细信息。