758

Is there a way in jQuery to loop through or assign to an array all of the classes that are assigned to an element?

ex.

<div class="Lorem ipsum dolor_spec sit amet">Hello World!</div>

I will be looking for a "special" class as in "dolor_spec" above. I know that I could use hasClass() but the actual class name may not necessarily be known at the time.

4
  • If you don't know the class name at the time, preventing you from using hasClass(), how do you intend to know which one in the array it is? Commented Aug 4, 2009 at 13:05
  • I am designing a form where I am doing some preliminary validation with jQuery. I am appending the id of the input element to the class list of the error div if one is generated. I am then making it possible to click on the error div to focus the errant input element. This script is going to be used for more than one form. I therefore do not want to hard-code the ids in the script. Commented Aug 4, 2009 at 13:10
  • 1
    Right, I understand why you wouldn't want to hardcode. But if you take a moment to look over redsquare's example you'll see you've got to hardcode 'someClass' into the if block. Either way you could achieve this with a variable. Commented Aug 4, 2009 at 13:31
  • Rather than using the class attribute, you could have an error list variable inside your namespace which contained DOM references to the elements with errors. Thus eliminating the need to pull the attribute list each time, iterate it, find the DOM element, and focus it. Commented Aug 4, 2009 at 13:33

16 Answers 16

802

You can use document.getElementById('divId').className.split(/\s+/); to get you an array of class names.

Then you can iterate and find the one you want.

var classList = document.getElementById('divId').className.split(/\s+/);
for (var i = 0; i < classList.length; i++) {
    if (classList[i] === 'someClass') {
        //do something
    }
}

jQuery does not really help you here...

var classList = $('#divId').attr('class').split(/\s+/);
$.each(classList, function(index, item) {
    if (item === 'someClass') {
        //do something
    }
});

You can use

if ($('#divId').hasClass('someClass')) {
    //do something
}
Sign up to request clarification or add additional context in comments.

3 Comments

that is exactly what i woud have done, but i was not sure if there was a build in jQuery function that gave you a collection of the classes.
FYI: jQuery uses className.split(/\s+/)
Add a jQuery plugin yourself: $.fn.classList = function() {return this[0].className.split(/\s+/);};
345

Why has no one simply listed.

$(element).attr("class").split(/\s+/);

EDIT: Split on /\s+/ instead of ' ' to fix @MarkAmery's objection. (Thanks @YashaOlatoto.)

6 Comments

That is part of the accepted answer... I needed all the classes that were applied to an element.
Haha, true! I wanted just this. It returns a string of classes separated by spaces, so maybe if you want to pick up one of them you can split the string by space and get an array to pick up a class from
Because it's wrong! Classes can be separated by any kind of whitespace (e.g. you can wrap a long class attribute in your HTML onto multiple lines), but this answer fails to account for that. Try pasting $('<div class="foo bar baz">').attr("class").split(' ') into your browser console (there's a tab character in there); you'll get ["foo", "bar baz"] instead of the correct class list of ["foo", "bar", "baz"].
@MarkAmery is right. If you would have a class="foo <lots of spaces here> bar", you would end up with an array with empty string elements.
@JacobvanLingen Is it possible to have lots of spaces between classes in modern browsers?
|
171

On supporting browsers, you can use DOM elements' classList property.

$(element)[0].classList

It is an array-like object listing all of the classes the element has.

If you need to support old browser versions that don't support the classList property, the linked MDN page also includes a shim for it - although even the shim won't work on Internet Explorer versions below IE 8.

2 Comments

@Marco Sulla: this has indeed a shortcoming other than support on obsolete software. .classList is not a true array, and such methods as .indexOf(⋯) don’t work on it. It is only an “array-like object”, whereas .className.split(/\s+/).indexOf(⋯) (from the accepted answer) works.
You can easily convert any iterable to an Array using [...iterable] or Array.from(iterable)
142

Here is a jQuery plugin which will return an array of all the classes the matched element(s) have

;!(function ($) {
    $.fn.classes = function (callback) {
        var classes = [];
        $.each(this, function (i, v) {
            var splitClassName = v.className.split(/\s+/);
            for (var j = 0; j < splitClassName.length; j++) {
                var className = splitClassName[j];
                if (-1 === classes.indexOf(className)) {
                    classes.push(className);
                }
            }
        });
        if ('function' === typeof callback) {
            for (var i in classes) {
                callback(classes[i]);
            }
        }
        return classes;
    };
})(jQuery);

Use it like

$('div').classes();

In your case returns

["Lorem", "ipsum", "dolor_spec", "sit", "amet"]

You can also pass a function to the method to be called on each class

$('div').classes(
    function(c) {
        // do something with each class
    }
);

Here is a jsFiddle I set up to demonstrate and test http://jsfiddle.net/GD8Qn/8/

Minified Javascript

;!function(e){e.fn.classes=function(t){var n=[];e.each(this,function(e,t){var r=t.className.split(/\s+/);for(var i in r){var s=r[i];if(-1===n.indexOf(s)){n.push(s)}}});if("function"===typeof t){for(var r in n){t(n[r])}}return n}}(jQuery);

Comments

108

You should try this one:

$("selector").prop("classList")

It returns a list of all current classes of the element.

5 Comments

Well I don't know. But this is the proper way to get property from DOM element. And "classList" is such property that gives you an array of css classes applied to the element.
@RozzA Maybe it wasn't available back then? But I'd say this is the most appropriate method as of now, unless you don't use jQuery, where a simple .classList is the solution - you just need to pay attention to inconsistencies and/or missing browser support..
@Dennis98 good call, I forget sometimes how rapidly new features have come out recently. I've also done plain js .classList it works quite well in modern browsers
Note that the classList property doesn't work on IE 10/11 for SVG elements (though it works for HTML elements). See developer.mozilla.org/en-US/docs/Web/API/Element/classList
@Métoule also .prop('classList') may not work in IE9 for HTML elements.
17
var classList = $(element).attr('class').split(/\s+/);
$(classList).each(function(index){

     //do something

});

Comments

8

Update:

As @Ryan Leonard pointed out correctly, my answer doesn't really fix the point I made my self... You need to both trim and remove double spaces with (for example) string.replace(/ +/g, " ").. Or you could split the el.className and then remove empty values with (for example) arr.filter(Boolean).

const classes = element.className.split(' ').filter(Boolean);

or more modern

const classes = element.classList;

Old:

With all the given answers, you should never forget to user .trim() (or $.trim())

Because classes gets added and removed, it can happen that there are multiple spaces between class string.. e.g. 'class1 class2       class3'..

This would turn into ['class1', 'class2','','','', 'class3']..

When you use trim, all multiple spaces get removed..

5 Comments

This is incorrect (and not an answer). Both String.trim() and $.trim() remove all leading and trailing whitespace, and leave the rest of the string alone. jsconsole.com/?%22%20%20a%20%20b%20%20%22.trim()
Did you even had a look at the answers? All the native JS solutions did not check for leading and trailing whitespaces, thus giving a faulty class list, as there would be empty classes in the array.. jQuery does the same internally with trim when it reads the classes
I did see the other answers, and agree that whitespace should be removed between class names. I was pointing out that a) this should be a comment on the other solutions, as it isn't a complete answer b) .trim() does not remove multiple spaces to achieve what you need.
You are totally correct indeed... Sorry for my to-quick comment.. It doesn't remove the spaces in between... s.trim().replace(/ +/g, " ") or something would be needed to remove all multiple spaces in between classes.. Next to that, el.classList is almost widely supported, fixing it all I suppose..
no problem at all. Happily upvoted, .classList is a much cleaner approach!
8
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})

1 Comment

This is a horrible abuse of .map; use .each if you don't need .map's return value. Splitting on spaces rather than any whitespace is also broken - see my comment on stackoverflow.com/a/10159062/1709587. Even if none of these points were true, this adds nothing new to the page. -1!
3

Might this can help you too. I have used this function to get classes of childern element..

function getClickClicked(){
    var clickedElement=null;
    var classes = null;<--- this is array
    ELEMENT.on("click",function(e){//<-- where element can div,p span, or any id also a class
        clickedElement = $(e.target);
        classes = clickedElement.attr("class").split(" ");
        for(var i = 0; i<classes.length;i++){
            console.log(classes[i]);
        }
        e.preventDefault();
    });
}

In your case you want doler_ipsum class u can do like this now calsses[2];.

Comments

3

For getting the list of classes applied to element we can use

$('#elementID').prop('classList')

For adding or removing any classes we can follow as below.

$('#elementID').prop('classList').add('yourClassName')
$('#elementID').prop('classList').remove('yourClassName')

And for simply checking if the class is present or not we can use hasClass

4 Comments

does not answer the question
@Aurovrata $('#elementID').prop('classList') was for getting the List of classes of the element and further, .add and .remove methods for doing changes to the list of classes. Isn't the question asking how to get class list in JQuery?
Indeed, the question specifically asks how to get the classlist so as to loop through it, nothing mentioned about adding or removing classes. Furthermore, you answer fails to explain what it does. Please consider improving it.
@Aurovrata: Thanks, I have improved the answer, please feel free to improve it further as per the requirement.
2

Thanks for this - I was having a similar issue, as I'm trying to programatically relate objects will hierarchical class names, even though those names might not necessarily be known to my script.

In my script, I want an <a> tag to turn help text on/off by giving the <a> tag [some_class] plus the class of toggle, and then giving it's help text the class of [some_class]_toggle. This code is successfully finding the related elements using jQuery:

$("a.toggle").toggle(function(){toggleHelp($(this), false);}, function(){toggleHelp($(this), true);});

function toggleHelp(obj, mode){
    var classList = obj.attr('class').split(/\s+/);
    $.each( classList, function(index, item){
    if (item.indexOf("_toggle") > 0) {
       var targetClass = "." + item.replace("_toggle", "");
       if(mode===false){$(targetClass).removeClass("off");}
       else{$(targetClass).addClass("off");}
    }
    });
} 

2 Comments

Thanks Alan, I'm doing something similar, I'm surprised that there isn't a simpler way to do this.
-​1 - tl;dr, goes off on a tangent not directly relevant to the question.
2

Try This. This will get you the names of all the classes from all the elements of document.

$(document).ready(function() {
var currentHtml="";
$('*').each(function() {
    if ($(this).hasClass('') === false) {
        var class_name = $(this).attr('class');
        if (class_name.match(/\s/g)){
            var newClasses= class_name.split(' ');
            for (var i = 0; i <= newClasses.length - 1; i++) {
                if (currentHtml.indexOf(newClasses[i]) <0) {
                    currentHtml += "."+newClasses[i]+"<br>{<br><br>}<br>"
                }
            }
        }
        else
        {
            if (currentHtml.indexOf(class_name) <0) {
                currentHtml += "."+class_name+"<br>{<br><br>}<br>"
            }
        }
    }
    else
    {
        console.log("none");
    }
});
$("#Test").html(currentHtml);

});

Here is the working example: https://jsfiddle.net/raju_sumit/2xu1ujoy/3/

Comments

1

I had a similar issue, for an element of type image. I needed to check whether the element was of a certain class. First I tried with:

$('<img>').hasClass("nameOfMyClass"); 

but I got a nice "this function is not available for this element".

Then I inspected my element on the DOM explorer and I saw a very nice attribute that I could use: className. It contained the names of all the classes of my element separated by blank spaces.

$('img').className // it contains "class1 class2 class3"

Once you get this, just split the string as usual.

In my case this worked:

var listOfClassesOfMyElement= $('img').className.split(" ");

I am assuming this would work with other kinds of elements (besides img).

Hope it helps.

Comments

-1

javascript provides a classList attribute for a node element in dom. Simply using

  element.classList

will return a object of form

  DOMTokenList {0: "class1", 1: "class2", 2: "class3", length: 3, item: function, contains: function, add: function, remove: function…}

The object has functions like contains, add, remove which you can use

2 Comments

Inferior duplicate of stackoverflow.com/a/5457148/1709587 which was posted 3 years before you; -1.
question specifically asks for jQuery solution
-3

A bit late, but using the extend() function lets you call "hasClass()" on any element, e.g.:
var hasClass = $('#divId').hasClass('someClass');

(function($) {
$.extend({
    hasClass: new function(className) {
        var classAttr = $J(this).attr('class');
        if (classAttr != null && classAttr != undefined) {
            var classList = classAttr.split(/\s+/);
            for(var ix = 0, len = classList.length;ix < len;ix++) {
                if (className === classList[ix]) {
                    return true;
                }
            }
        }
        return false;
    }
}); })(jQuery);

2 Comments

That was not the question.
Also, jQuery has had this function built-in since version 1.2.
-3

The question is what Jquery is designed to do.

$('.dolor_spec').each(function(){ //do stuff

And why has no one given .find() as an answer?

$('div').find('.dolor_spec').each(function(){
  ..
});

There is also classList for non-IE browsers:

if element.classList.contains("dolor_spec") {  //do stuff

1 Comment

-​1; among other problems, your first two code snippets are unrelated to the question asked and your final snippet is a syntax error.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.