jQuery selector: Selecting a certain combination o

2019-06-19 02:15发布

问题:

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!

回答1:

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.



回答2:

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;
  });
}


回答3:

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');