1

I was given an eshop after someone else who wasnt really caring about the site performance and made a really anti-performance CSS, and since no CSS minifyer works crossbrowser-properly on such a huge CSS file (not even eshop's own) I decided to clear CSS by myself, to do that I would need complete list of classes used on page - how to get complete list of classes used on the page in jQuery?

(Somtehing I could e.g. loop-write into console,... And I am looking rather for a how to do in jQuery than a complete solution (In such things I never belive third-side x) )

jave.web
  • 13,880
  • 12
  • 91
  • 125
  • 2
    check this topic http://stackoverflow.com/questions/2787291/use-jquery-to-get-a-list-of-classes – Lukas Aug 07 '13 at 08:39
  • this may also help you http://stackoverflow.com/questions/4651834/listing-known-css-classes-using-javascript – Bhojendra Rauniyar Aug 07 '13 at 08:45
  • @Lukas - thank you but my question was heading more to how to crawl through all elements actually I know how to get all classes from one element - anyway great tip for others! :) – jave.web Aug 07 '13 at 08:58
  • @C-Link - interesting link - it has nothing to do with this issue, but I may use it later :) – jave.web Aug 07 '13 at 08:59

8 Answers8

5

jQuery has an attribute selector - choose only elements which have class atribute :) Then split class attribute string (for cases like class="one two") and add them to array (dont forget to check if class is not empty or isnt already in the array. Use this.valueOf() for checking and saving the string :)

var classes = [];
$('[class]').each(function(){
    $($(this).attr('class').split(' ')).each(function() { 
        if (this.length>0 && $.inArray(this.valueOf(), classes) === -1) {
            classes.push(this.valueOf());
        }    
    });
});
console.log("LIST START\n\n"+classes.join('\n')+"\n\nLIST END");

JSFiddle link : http://jsfiddle.net/MWJKL/

jave.web
  • 13,880
  • 12
  • 91
  • 125
Aditya
  • 4,453
  • 3
  • 28
  • 39
3

Check only elements with the class attribute and split the value so you don't get duplicates

var classes = [];
$('[class]').each(function(){
    $.each($(this).attr('class').split(' '),function(i,className) { 
        if (className.length && $.inArray(className, classes) === -1) {
            classes.push(className);
        }    
    });
});
console.log(classes.join(','));

EDIT Fixed to iterate over an array instead of a jQuery object

omma2289
  • 54,161
  • 8
  • 64
  • 68
2
$(function(){

    var result = [];    

    $('*').each(function(k, v){

        var classNames = $(v).prop('class');

        if(classNames){

            var classes = classNames.split(' ');

            $.each(classes, function(k2, v2){

                if($.inArray(v2, result) === -1)
                    result.push(v2);
            });
        }

    });

    console.log(result);

});

http://jsfiddle.net/ZQZ8j/1/

Johan
  • 35,120
  • 54
  • 178
  • 293
  • This one is really good too (vote up), but there is no need to go through the whole javascript scoping if we have JS native valueOf() :) – jave.web Aug 07 '13 at 10:32
  • @jave.web I'm aware that this can be written in a shorter and more optimized way. I wrote it like this because my intention was to make it readable for someone who's not very familiar with jQuery – Johan Aug 07 '13 at 10:34
1
jQuery("*").each(function () {
    var thisEl = jQuery(this);
    var thisClass = thisEl.attr("class");
    if (thisClass != undefined) { console.log(thisClass); }
});
David MacCrimmon
  • 966
  • 1
  • 6
  • 19
  • I give you vote up, because its actually working, BUT not correctly it considers more classes in class attribute as one class :) – jave.web Aug 07 '13 at 09:06
1

Try

$(function(){
    var temp = {};    

    $('*').each(function(idx, el){
        var classNames = el.className;
        if(classNames){
            var classes = classNames.split(' ');
            $.each(classes, function(idx, clazz){
                temp[clazz] = true;
            });
        }
    });

    var result = $.map(temp, function(value, key){
        return key;
    })
    console.log(result);

});

Demo: Fiddle

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • This one really is good one I just like koala's solution more :) , sad you cant chose second best answer :( – jave.web Aug 07 '13 at 09:29
1

ES6 solution using classList and without jQuery

var classes = []
document.querySelectorAll('[class]').forEach((node) => {
  node.classList.forEach((className) => {
    classes.push(className)
  })
})
console.log(classes)
Sergey Bezugliy
  • 580
  • 7
  • 23
  • Gave upvote for future, but although not explicitly, the question implies unique list (as in accepted answer) - I have a suggestion - what about using even more ES6 - `Set`s ? Super fast, **auto**unique :-) - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set , basically using `new Set()` instead of `[]` and `.add(...)` instead of `.push(...)` should be enough (note that with Sets you DON'T need any uniqueness checking before adding item it does it natively :-) ) Tested, works super fast - https://jsfiddle.net/w1u8kq4g/ – jave.web Jan 05 '22 at 17:09
0

I think you can use Firefox extension Dust-Me that finds unused CSS selectors.

Mahmood Kohansal
  • 1,021
  • 2
  • 16
  • 42
0

You can jQuery has attribute selector

$("*[class]").each(function () {
    var classNames = this.attr("class");
    // Split classNames as shown in other answers
});

It will select elements which have the class attribute so no need to add check for undefined.

Ajinkya
  • 22,324
  • 33
  • 110
  • 161
  • You seem to be messed up from other languages - this cant even work because you breaking two things: class is a reserved JavaScript word (cant name variable "classs") and you are calling jquery attr() method on non-jquery object ... you ment this: http://jsfiddle.net/eUH7N/ – jave.web Aug 07 '13 at 09:11