694
votes

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.

16
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?doomspork
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.Buggabill
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.doomspork
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.doomspork

16 Answers

759
votes

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

Why has no one simply listed.

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

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

158
votes

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.

141
votes

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);
87
votes

You should try this one:

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

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

17
votes
var classList = $(element).attr('class').split(/\s+/);
$(classList).each(function(index){

     //do something

});
7
votes

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..

7
votes
$('div').attr('class').split(' ').each(function(cls){ console.log(cls);})
3
votes

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];.

2
votes

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
votes

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/

1
votes

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.

1
votes

You can follow something like this.

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

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

-3
votes

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);
-3
votes

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