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



这个问题几乎相同,但在一个关键方面有所不同,最终无济于事:样式属性的顺序。

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

平等也应该考虑后代,并递归地应用此逻辑。也就是说,如果唯一的区别是样式属性的顺序,则具有相同后代的两个元素相等。(这在以前对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 元素之间的唯一区别是样式属性的顺序,您如何识别它们相等?

Node.isEqualNode() 确实比较了孩子。请参阅完整算法的规范(如果应用于元素):

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

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

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

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

Element.style返回一个同时包含字符串键和数字键的对象。第一个是包含所有现有 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>

我正在将其作为编辑添加到您的问题中,但是@Doğancan Arabacı 和 @Shree 拒绝了它,并说它更适合作为答案,尽管它只是修复了我认为是一个错误。

参考"如果两个 HTML 元素之间的唯一区别是样式属性的顺序,你怎么能将它们识别为相等?",即使样式属性相同,你的代码也会打印"不同",因为 id 和里面的文本仍然不同。

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

<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。

相关内容

  • 没有找到相关文章

最新更新