A. Wolff
A. Wolff

Reputation: 74420

compare two matched set of elements

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

Answers (5)

apsillers
apsillers

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

c-smile
c-smile

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

Selvakumar Arumugam
Selvakumar Arumugam

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

Adil Shaikh
Adil Shaikh

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

Jacob
Jacob

Reputation: 1553

to start with...

if($('div').isEqual('#mydiv1,#mydiv2'))

gives an error and sequenceEqual gives "false"

Upvotes: 0

Related Questions