我需要比较不同的选择器是否返回相同匹配的元素集。
我来到这个简单的解决方案,一个小插件:
;(function ($) {
$.fn.isEqual = function ($selector) {
return this.add().get().join() === $selector.add().get().join()
}
})(jQuery);
//e.g of usages: if($('div').isEqual($('#mydiv1,#mydiv2'))
//if($(':checkbox').isEqual($('input[type=checkbox].myclass'))
//if($('div').parents().isEqual($('body div').parents()) etc ...
现在我觉得我错过了一些东西,因为我找到的所有其他解决方案看起来都非常精细,就像这个似乎是特权的那个:
$.fn.sequenceEqual = function(compareTo) {
if (!compareTo || !compareTo.length || this.length !== compareTo.length) {
return false;
}
for (var i = 0, length = this.length; i < length; i++) {
if (this[i] !== compareTo[i])
return false;
}
}
return true;
}
那么,使用$ .isEqual插件会有什么不利之处?
答案 0 :(得分:5)
Array join()
将数组字符串化,因此您依赖于jQuery元素集的字符串化版本。 DOM元素字符串化为类似[object HTMLDivElement]
的字符串,所以实际上你只是比较每个jQuery对象中元素的大小,顺序和类型。
例如,
$("div:first").isEqual($("div:last"))
总是如此,因为两个选择器都捕获一个<div>
(即它们都串联成“[object HTMLDivElement]
”),但这个断言实际上应该是真的很少。
即使某些浏览器 提供了一种在字符串表示形式中唯一标识元素的方法,toString
的{{1}}行为也未被任何标准指定,因此您冒着跨浏览器兼容性的风险。 (但是,没有浏览器会这样做,因此您的代码无法在任何浏览器中正常运行。)
答案 1 :(得分:1)
正如你所说我需要比较不同的选择器是否返回相同匹配的元素集
这个简化的插件怎么样 -
;(function ($) {
$.fn.isEqual = function ($selector) {
return this.is($selector);
}
})(jQuery);
答案 2 :(得分:1)
.isEqual
和.sequenceEqual
不同的比较级别。
.isEqual
- 比较返回选择器的el.toString
。含义<div id="test"></div>
与<div id="test1"></div>
相同,$('#test').isEqual('#test1')
将返回true,因为比较基于toString
[object HTMLDivElement]
。
.sequenceEqual
进行节点比较,基本上遍历所有元素并逐一进行比较。
以上假设你的.add
错误存在。
DEMO: http://jsfiddle.net/2QYgp/
(function ($) {
$.fn.isEqual = function ($selector) {
return this.get().join() === $($selector).get().join()
}
})(jQuery);
$(function () {
alert($('#test1').isEqual('#test'));
});
答案 3 :(得分:1)
isEqual
假设DOMNode.toString()
生成一些唯一标识DOM节点的字符串。这是错误的假设。 W3C DOM规范未指定AFAIR DOMElement.toString()
,因此您无法依赖其结果 - 它们在不同的UA中会有所不同。
如果任务是测试相等性,那么sequenceEqual
是正确的,而不是相似性。
答案 4 :(得分:0)
开头......
if($('div').isEqual('#mydiv1,#mydiv2'))
给出错误,sequenceEqual给出“false”