开发者

jQuery hasClass() - check for more than one class

With:

if(element开发者_JAVA百科.hasClass("class"))

I can check for one class, but is there an easy way to check whether "element" has any of many classes?

I am using:

if(element.hasClass("class") || element.hasClass("class") ... )

Which isn't too bad, but I am thinking of something like:

if(element.hasClass("class", "class2")

Which unfortunately doesn't work.

Is there something like that?


element.is('.class1, .class2')

works, but it's 35% slower than

element.hasClass('class1') || element.hasClass('class2')

jQuery hasClass() - check for more than one class

See also this jsbench.me test.


How about:

element.is('.class1, .class2')


$.fn.extend({
    hasClasses: function (selectors) {
        var self = this;
        for (var i in selectors) {
            if ($(self).hasClass(selectors[i])) 
                return true;
        }
        return false;
    }
});

$('#element').hasClasses(['class1', 'class2', 'class3']);

This should do it, simple and easy.


filter() is another option

Reduce the set of matched elements to those that match the selector or pass the function's test.

$(selector).filter('.class1, .class2'); //Filter elements: class1 OR class2

$(selector).filter('.class1.class2'); // Filter elements: class1 AND class2


How about this?

if (element.hasClass("class1 class2")


here's an answer that does follow the syntax of

$(element).hasAnyOfClasses("class1","class2","class3")
(function($){
    $.fn.hasAnyOfClasses = function(){
        for(var i= 0, il=arguments.length; i<il; i++){
            if($self.hasClass(arguments[i])) return true;
        }
        return false;
    }
})(jQuery);

it's not the fastest, but its unambiguous and the solution i prefer. bench: http://jsperf.com/hasclasstest/10


What about:

if ($('.class.class2.class3').length) {
    //...
}


jQuery

if( ['class', 'class2'].some(c => [...element[0].classList].includes(c)) )

Vanilla JS

if( ['class', 'class2'].some(c => [...element.classList].includes(c)) )


What about this,

$.fn.extend({
     hasClasses: function( selector ) {
        var classNamesRegex = new RegExp("( " + selector.replace(/ +/g,"").replace(/,/g, " | ") + " )"),
            rclass = /[\n\t\r]/g,
            i = 0,
            l = this.length;
        for ( ; i < l; i++ ) {
            if ( this[i].nodeType === 1 && classNamesRegex.test((" " + this[i].className + " ").replace(rclass, " "))) {
                return true;
            }
        }
        return false;
    }
});

Easy to use,

if ( $("selector").hasClasses("class1, class2, class3") ) {
  //Yes It does
}

And It seems to be faster, http://jsperf.com/hasclasstest/7


This is quite old, but hear me out on this one.

$.fn.extend({
  hasClasses: function (selectors) {
      // Setup
      const _id = $(this).attr('id'); // Preserve existing id
      const uuid = generateUUID();    // Create new id for query
      $(this).attr('id', uuid);       // Apply new id to element
     
      // Query to find if element has any of the classes
      const res = selectors.some(cls => !!$(`${uuid}.${cls}`).length);
      
      // Rollback on id 
      if (!_id) $(this).removeAttr("id"); // No Id to begin with
      else $(this).attr('id', _id);       // Preserve old id
      
      // Done
      return res;
    }
})

Instead of trying to find a match between one of the classes in selectors and one of the element's classes we simply apply a temporary id (uuid) to the element and query to find if there exists some element with that temporary id and any of the classes listed in selectors.

This inspired by Kalel Wade's and Simon Arnold's solution but with a minor improvement to performance (benchmarked on jsbench.me).

Note

JSBENCH doesn't allow saving over a limit of a certain amount of characters or words. I had some trouble with the async fetching of random words, so you can get random words manually and use the bench that way.

EDIT:

I just noticed that for my implementation of this I am relying on the id with async calls. I might cause an issue if I need to query the element by id the same time that hasClasses changes the id.

To circumvent this we can just add a unique uuid attribute (literally just the uuid).

Here is the correction:

$.fn.extend({
  hasClasses: function (selectors) {
    // Setup
    const uuid = generateUUID(); // Create new uuid to query later
    $(this).attr(uuid, "");      // Apply uuid to element for query

    // Query to find if element has any of the classes
    const res = selectors.some(cls => !!$(`[${uuid}].${cls}`).length);

    // Remove the uuid attribute
    $(this).removeAttr(uuid);

    // Done
    return res;
  }
})

We could still use an the elements' id if it has one instead of adding an attribute.
I'm not sure if querying ids is faster or not. I referenced this, but by the looks of it there isn't much of a hit with modern browsers. Could still implement using the id if it exists instead of an attribute.


use default js match() function:

if( element.attr('class') !== undefined && element.attr('class').match(/class1|class2|class3|class4|class5/) ) {
  console.log("match");
}

to use variables in regexp, use this:

var reg = new RegExp(variable, 'g');
$(this).match(reg);

by the way, this is the fastest way: http://jsperf.com/hasclass-vs-is-stackoverflow/22


You can do this way:

if($(selector).filter('.class1, .class2').length){
    // Or logic
}

if($(selector).filter('.class1.class2').length){
    // And logic
}


This worked for me:

$('.class1[class~="class2"]').append('something');


Works for me:

 if ( $("element").hasClass( "class1") || $("element").hasClass("class2") ) {

 //do something here

 }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜