Senseful
Senseful

Reputation: 91691

How do I check if 2 jQuery selectors are pointing to the same element(s)?

If I try something such as this:

$(".foo") === $(".foo") // = false

... I get false. If I instead try this query,

$(".foo").get(0) === $(".foo").get(0) // = true

... I get true.

That's because:

{a:myObject} !== {a:myObject};
[myObject]   !== [myObject];
myObject     === myObject;

I'm wondering if there is any succinct way to test for this equality, preferably built into jQuery. The 2nd method I wrote only works correctly if there is at most one element which matches .foo. The solution should work for any amount of elements.

Obviously I don't want to just check ".foo" === ".foo" since the actual selections I'm using are more complicated. I just simplified them for this example. (E.g. I may want to check that $(this) is selecting the same thing as $(".foo").)

Upvotes: 14

Views: 5083

Answers (5)

Rich O'Kelly
Rich O'Kelly

Reputation: 41757

There is nothing in the core library to check sequence equality of jQuery objects, however the following should do the trick:

$.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;
} 

Which would be useable like so:

$(".foo").sequenceEqual($(".bar"))

For completeness, a contents equal method could be written like so:

$.fn.contentsEqual = function(compareTo) {
  return compareTo && this.length === compareTo.length && this.length === this.filter(compareTo).length;
}

Which would be useable like so:

$(".foo").contentsEqual($(".bar"))

Upvotes: 8

benekastah
benekastah

Reputation: 5711

I think you are looking for $().is. Docs here.

var foo, bar;

foo = $('foo');
bar = $('.bar');

// This will check to see foo and bar contain the same elements
foo.is(bar); // true | false

Edit: @lolwut provided a jsfiddle for this answer. After reading the comments, I updated it and determined that this answer isn't reliable for the OP's case.

Upvotes: 14

pimvdb
pimvdb

Reputation: 154838

If you want to check whether both sets contain exactly the same elements (possibly in a different order), then Array#every in combination with $.fn.index could do the job:

var $this  = $("p"),
    $other = $("p");


// same length and $other contains each element of $this

var equal = $this.length === $other.length
              && Array.prototype.every.call($this, function(elem) {
                   return $other.index(elem) > -1;
                 });

Upvotes: 4

Fr&#233;d&#233;ric Hamidi
Fr&#233;d&#233;ric Hamidi

Reputation: 262959

As an alternative to pimvdb's answer (which is very nice, I'm only providing this for completeness), you can leverage the fact that add() will not add elements that are already present in the jQuery object. Therefore, you can write:

$.fn.containsSameElements = function(other) {
    var len = this.length;
    return other.length == len && this.add(other).length == len;
};

Upvotes: 3

georg
georg

Reputation: 214969

Ok, using only jquery builtins, this seems to be the right one

$(oneSelector).filter($(anotherSelector)).length == 1

if ($(oneSelector).is($(anotherSelector)))... they are equal

Upvotes: -1

Related Questions