Skip to content

Instantly share code, notes, and snippets.

@fredoliveira
Created January 11, 2011 06:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save fredoliveira/774111 to your computer and use it in GitHub Desktop.
Save fredoliveira/774111 to your computer and use it in GitHub Desktop.
Work in progress for an unused CSS selector javascript utility
(function() {
var s=document.createElement('script');
s.setAttribute('src','https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js');
if(typeof jQuery!='undefined') {
var msg='This page already using jQuery v' + jQuery.fn.jquery;
} else {
document.getElementsByTagName('head')[0].appendChild(s);
var msg='This page is now jQuerified'
}
window.setTimeout(function() {
jQuery.noConflict();
jQuery(document).ready(function() {
var existing_classes = [];
var defined_classes = [];
var unused_classes = [];
jQuery('body').find('*').each(function(){
if(jQuery(this)[0].className) {
jQuery.each(jQuery(this)[0].className.split(' '), function(i,v) {
existing_classes.push(v);
});
}
});
for(i=0; i<document.styleSheets.length; i++) {
rules = document.styleSheets[i].cssRules;
for(var j = 0; j < rules.length; j++) {
jQuery.each(rules[j].selectorText.split(' '), function(i,v) {
if(v.charAt(0) == '.') {
defined_classes.push(v.slice(1));
}
});
}
};
jQuery.each(defined_classes, function(i,v) {
if(jQuery.inArray(v, existing_classes) != 1) {
unused_classes.push(v);
}
});
console.log(existing_classes);
console.log(defined_classes);
console.log(unused_classes);
});
}, 2500);
})();
jQuery.noConflict();
jQuery(document).ready(function() {
var existing_classes = []; // includes classes in the current document
var defined_classes = []; // includes classes defined in the CSS
var unused_classes = []; // classes defined in the CSS, not used in the document
// go through each node in the DOM
// (we ignore things outside the body element)
// (those are quite rare)
jQuery('body').find('*').each(function(){
if(jQuery(this)[0].className) {
// for each element, grab all classes and push them into
// our existing_classes array
jQuery.each(jQuery(this)[0].className.split(" "), function(i,v) {
existing_classes.push(v);
});
}
});
// go through our document stylesheets
// extract the selector text from each rule
for(i=0; i<document.styleSheets.length; i++) {
rules = document.styleSheets[i].cssRules;
for(var j = 0; j < rules.length; j++) {
// go through each CSS rule, and split the selector text
jQuery.each(rules[j].selectorText.split(" "), function(i,v) {
// if the selector defines a class, add it to the defined_classes array
// note: this is probably quite crude (and slow for large documents),
// but works for 90% of cases
if(v.charAt(0) == ".") {
defined_classes.push(v.slice(1));
}
});
}
}
// work some array magic
// go through our defined classes and see if they're being used
// if not, add them to our unused_classes array
jQuery.each(defined_classes, function(i,v) {
if(jQuery.inArray(v, existing_classes) != 1) {
unused_classes.push(v);
}
});
// print classes used in this document
console.log(existing_classes);
// print classes declared by the stylesheets
console.log(defined_classes);
// the money shot. print unused classes
console.log(unused_classes);
});
@samageloff
Copy link

Thanks for this. You just need to do a check for rules[j].selectorText for selectors that don't have it (eg: font declarations):

for(var j = 0; j < rules.length; j++) {
    if (rules[j].selectorText) {
        jQuery.each(rules[j].selectorText.split(' '), function(i,v) {
            if(v.charAt(0) == '.') {
                defined_classes.push(v.slice(1));
            }
        });
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment