Reputation: 74420
I need to compare if different selectors returns same matched set of elements.
I came to this easy solution, a little plugin:
;(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 ...
Now i think i'm missing something as all other solutions i have find seems really more elaborate, like this one which seems to be the privileged one:
$.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;
}
So, what can be the downside of using $.isEqual plugin?
Upvotes: 2
Views: 245
Reputation: 115930
Array's join()
stringifies an array, so you're relying on the stringified versions of the jQuery set of elements. DOM elements stringify into a string like [object HTMLDivElement]
, so really you're only comparing the size, order, and types of the elements in each jQuery object.
For example,
$("div:first").isEqual($("div:last"))
will be true always, because both selectors capture one <div>
(i.e., they both stringify into "[object HTMLDivElement]
"), but very rarely should this assertion actually be true.
Even if some browsers did supply a way to uniquely identify elements in their string representations, the toString
behavior of HTMLElement
s is not specified by any standard, so you'd run the risk of cross-browser compatibility. (As it stands, however, no browser does so, so your code doesn't work correctly in any browser.)
Upvotes: 5
Reputation: 27460
That isEqual
assumes that DOMNode.toString()
produces some string that uniquely identifies DOM nodes. And that is wrong assumption. AFAIR DOMElement.toString()
is not specified by W3C DOM specs so you cannot rely on its results - they will be different in different UAs.
That sequenceEqual
is correct if the task is to test equality, but not, say, similarity.
Upvotes: 1
Reputation: 79830
The level of comparison that your .isEqual
and .sequenceEqual
is different.
.isEqual
- Compares the el.toString
of returned selectors. Meaning <div id="test"></div>
will be same as <div id="test1"></div>
and $('#test').isEqual('#test1')
would return true as the comparison is based on toString
which is [object HTMLDivElement]
.
.sequenceEqual
does a node comparision which basically iterates through all elements and compares it one by one.
Above is with the assumption that your .add
is there by mistake.
DEMO: http://jsfiddle.net/2QYgp/
(function ($) {
$.fn.isEqual = function ($selector) {
return this.get().join() === $($selector).get().join()
}
})(jQuery);
$(function () {
alert($('#test1').isEqual('#test'));
});
Upvotes: 1
Reputation: 44740
As you said I need to compare if different selectors returns same matched set of elements
How about this simplified plugin -
;(function ($) {
$.fn.isEqual = function ($selector) {
return this.is($selector);
}
})(jQuery);
Upvotes: 1
Reputation: 1553
to start with...
if($('div').isEqual('#mydiv1,#mydiv2'))
gives an error and sequenceEqual gives "false"
Upvotes: 0