dmb
dmb

Reputation: 603

jQuery method to select a subset and also its inverse?

Given some jQuery object set, and also a subset of that set, is there a method that will return the inverse subset?

If the answer is "No", is there any way to avoid making a second selection to get the inverse subset?

Explanatory example:

<ul>
  <li class="subset"></li>
  <li class="subset"></li>
  <li class="inverse"></li>
  <li class="inverse"></li>
</ul>

First I want to do something to all the <li>, then something to only .subset, and finally something else to only .inverse:

$('li').css('background-color','blue')
  .filter('.subset')
    .css('color','black')
  .inverse()  // <-- White Whale?!?
    .css('color','white');

I know this could be easily done with .end().filter('.inverse'), but suppose the selector were actually big and nasty and running it twice would be a big performance hit. What then?

Haven't found anything like this in the API docs, but I'm new to jQuery and may have overlooked something obvious (also, the existence of .andSelf() means this would not be unreasonable to expect...).

Upvotes: 3

Views: 2168

Answers (2)

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196236

Here is a little extension to jquery about it that i just made..

(function($) {
  $.fn.reverse = function () 
  {
      var orig = this.prevObject || jQuery(null);
      return orig.not(this);
  }
})(jQuery);

It will maintain the chaining, so you can still do .end() after it and return to the previous filtering.

You can call it like

$('li').css('background-color','blue')
  .filter('.subset')
    .css('color','black')
  .reverse()  // <-- White Whale?!?
    .css('color','white');

Demo with your example: http://www.jsfiddle.net/gaby/THLkn/

Upvotes: 1

Nick Craver
Nick Craver

Reputation: 630607

There's no built-in function for this, the reverse filter is what you're after...the alternative isn't chainable. The alternative would be .not(), like this:

var all = $('li').css('background-color','blue');
var sub = all.filter('.subset').css('color','black');
all.not(sub).css('color','white');

...but again it's not pretty, I'd stick with the .end().filter() approach. However, if performance is paramount, use the .not() approach above, it is more efficient (since no selector runs for the inverse set).


For your specific example (though not the general question), it'd be pretty quick to do this:

$('li').css('background-color','blue').css('color','white')
       .filter('.subset').css('color','black');

Upvotes: 5

Related Questions