比较样式属性顺序无关的两个HTML元素

时间:2019-06-20 08:06:36

标签: javascript jquery html

This question几乎相同,但是在一个关键方面有所不同,最终没有帮助:样式属性的顺序。

也就是说,具有相同样式属性(但顺序不同)的两个元素应视为等效。

平等还应该考虑后代,并递归地应用此逻辑。也就是说,如果唯一的区别是样式属性的顺序,则具有相同后代的两个元素是相等的。 (以前对IsEqualNode的过时理解就暗示了这一点,该观点认为孩子是旧规范的孩子,而不再是新规范的孩子。)

但是,评分最高的答案将两个这样的元素视为不同,如下所示:

<div style="color: red; font-size: 28px">TEST A</div>
<div style="font-size: 28px; color: red">TEST A</div>

if ($("div")[0].isEqualNode($("div")[1])) {
  alert("Same");
} else {
  alert("Different");
}

如果两个HTML元素之间唯一的区别是样式属性的顺序,您怎么能将它们识别为相等?

2 个答案:

答案 0 :(得分:2)

Node.isEqualNode()确实比较了孩子。如果适用于元素,请参见spec了解完整算法:

  

如果满足以下所有条件,则节点A等于节点B:

     
      
  • A和B的nodeType属性值相同。
  •   
  • 以下内容也相等...:      
        
    • [元素:]其名称空间,名称空间前缀,本地名称及其属性列表中的属性数量。
    •   
  •   
  • 如果A是元素,则其属性列表中的每个属性都具有一个属性,该属性具有与B的属性列表中相同的名称空间,本地名称和值。
  •   
  • A和B的孩子数相同。
  •   
  • 在相同的索引处,A的每个孩子等于B的孩子。
  •   

问题仍然是style属性值的文本比较,并且相同的参数(功能上相同,但文本上不同)可以应用于class属性。

一种解决方案是生成一个克隆,该克隆的样式属性和类名称具有定义的(字母顺序)顺序。

Element.style返回带有字符串键和数字键的对象。第一个是包含现有 all CSS属性的列表,无论它们是否真的在style属性中设置。那是一个很长的列表,大多数条目都是空字符串。

这就是数字键的作用:该对象包含类似数组的条目,列出了所有实际设置的属性名称。将它们与Array.from()转换为实数组可以仅获取相关部分并对它们进行排序。

Element.classList是一个类似数组的列表。

这两个属性都被视为只读属性,因此要回写,请使用基本方法写入命名属性。

$.fn.normalizeTree = function () {
    return this.each(function () {
        $(this).add("*", this).each(function () {
            const sortedClass = Array.from(this.classList)
               .sort()
               .join(' ');
            $(this).attr('class', sortedClass);

            const sortedStyle = Array.from(this.style)
               .sort()
               .map(prop => `${prop}: ${this.style[prop]};`)
               .join();
            $(this).attr('style', sortedStyle);
        });
    });
}

const rawNodes = $(".comparable");

if (rawNodes[0].isEqualNode(rawNodes[1])) {
  $("#result1").text("equal")
}

const normalNodes = rawNodes.clone().normalizeTree();

if (normalNodes[0].isEqualNode(normalNodes[1])) {
  $("#result2").text("equal")
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="comparable">
  <p class="one two"><span style="color:rgb(0, 0, 0);font-family:sans-serif;font-size:15px">A text.</span></p>
</div>
<div class="comparable">
  <p class="two one"><span style="font-size:15px;font-family: sans-serif;color:rgb(0, 0, 0);">A text.</span></p>
</div>

<p>These are <span id="result1">not equal</span> if raw.</p>
<p>These are <span id="result2">not equal</span> if normalized.</p>

答案 1 :(得分:1)

我正在将此内容添加到您的问题中,但@DoğancanArabacı和@Shree拒绝了它,并说它更适合作为答案,尽管它只是解决了我认为是错误的问题。

参考“如果两个HTML元素之间唯一的区别是样式属性的顺序,您如何将它们识别为相等?”,即使样式属性相同,因为id和the相同,您的代码也会打印“ Different”里面的文字仍然不同。

因此,我将代码更改为此,唯一的区别是样式的顺序。我还没有评论权限,所以我需要这样做。

<div class="a" style="color: red; font-size: 28px;">TEST A</div>
<div class="a" style="font-size: 28px; color: red;">TEST A</div>

<script>
var x = document.getElementsByClassName("a");  
if (x[0].isEqualNode(x[1])) alert("Same");
else alert("Different");
</script>

我不认为其他答案是正确的,因为除了代码中样式的顺序以外,还有更多差异,因此无论如何它都应打印为false。