Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery selector: Selecting a certain combination of classes when multiple exist

I have tried to do some research already and haven't found anything, but If I've missed the answer, please tell me. Basically I have multiple elements with multiple classes each, but the combinations are unique. I want to select a certain combination of classes, but not other elements that have this elements in combination with others.

I would like to know if this selector exists in jQuery or if there is some other way to accomplish what I am explaining. See the example below:

<div class="a b c"></div>
<div class="a b c d"></div>
<div class="a b c d">/div>

When trying to log only the element with the classes a b c, I tried using:

$('.a.b.c').each( function() {
    console.log($(this));
}

the output is:

[ <div class="a b c">...</div> ,
<div class="a b c d">...</div ,
<div class="a b c d">...</div> ]

I am looking for the output to be:

[ <div class="a b c">...</div> ]

Any guidance is appreciated. Thanks!

like image 314
Wold Avatar asked Feb 07 '15 00:02

Wold


People also ask

How can I select an element with multiple classes in jQuery?

The . class selector can also be used to select multiple classes. Note: Seperate each class with a comma. Note: Do not start a class attribute with a number.

How do you find the element of multiple classes?

Use the getElementsByClassName method to get elements by multiple class names, e.g. document. getElementsByClassName('box green') . The method returns an array-like object containing all the elements that have all of the given class names.

How do I select a specific class in jQuery?

In jQuery, the class and ID selectors are the same as in CSS. If you want to select elements with a certain class, use a dot ( . ) and the class name. If you want to select elements with a certain ID, use the hash symbol ( # ) and the ID name.


3 Answers

You could use the CSS3 :not() pseudo class to negate the .d class: (example)

$('.a.b.c:not(.d)').each( function() {
    console.log($(this));
});

jQuery also has a .not() method: (example)

$('.a.b.c').not('.d').each( function() {
    console.log($(this));
});

You could also use the attribute selector: (example)

[class="a b c"]

Note that the order always has to be a b c. Just throwing that out there as an option.

like image 195
Josh Crozier Avatar answered Oct 21 '22 04:10

Josh Crozier


I don't believe you can do this with straight CSS selectors, short of using :not to enumerate every other class you wish to exclude or some real gymnastics with [class=]. However, what you can do is select all elements with the .a.b.c classes, and then filter out any elements that have more than three elements in their class list:

var $abcDivs = $('.a.b.c').filter(function(i, $elem){
  return $elem.attr("class").split(' ').length == 3;
})

More generally:

function exactClass(classList) {
  return $(classList.join('.')).filter(function(i, $elem){
    return $elem.attr("class").split(' ').length == classList.length;
  });
}
like image 20
rmehlinger Avatar answered Oct 21 '22 04:10

rmehlinger


I've been looking for something similar a while ago, but I was not able to guess what classes I do not need (as they were appended dynamically). So, instead of excluding unwanted classes with not(), I made this to match elements with only classes I know of.

var classes = ['a','c','b'];

$('.'+classes.join('.')).each( function(){
  var cl = $(this).attr('class');
  for(var i in classes) {
    cl = cl.split(classes[i]).join('');
  }
  if(cl.replace(/\s+/, '') === ''){
    $(this).addClass('blah');
  }
});
.blah{
    font-size:30px;
    color : red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="a b c d">Foo</div>
<div class="c b a">Bar</div>
<div class=" a b  c">Hello</div>
<div class=" a b">World</div>

JSFiddle . As a method:

function el(c){
    var a = [];
    $('.'+c.join('.')).each(function(){
        var k = $(this).attr('class');
        for(var i in c) k=k.split(c[i]).join('');
        if(k.replace(/\s+/,'')==='') a.push(this);
    });
    return a;
}

// usage:
$(el(['a','c','b'])).addClass('blah');
like image 31
Artur Filipiak Avatar answered Oct 21 '22 05:10

Artur Filipiak