Reputation: 1234
How can I get a list of all class names used inside an HTML Snippet?
For example, the HTML Snippet below,
<div class="name">
<div class="first"></div>
<div class="last"></div>
</div>
would have output name
, first
, last
or name
, name > first
, name > last
. Here, I am concerned about finding all class selectors first. Nesting could be optional.
I expect to use Javascript or Regular Expressions.
Upvotes: 10
Views: 27393
Reputation: 11
Correction to KR Thirto's reply:
const allClasses = new Set(
Array.from(document.querySelectorAll("*"))
.map( (el) => el.className )
);
const flatClasses = new Set(
Array.from(allClasses)
.map((el) => el.split(/\s+/g))
.flat(1)
.filter((el) => el)
);
First we map the classname property for all DOM nodes into a set. This classname property contains the actual classnames, separated by a space.
As split() returns an array, splitting the classname property within allClasses will result in an array where some elements are strings, and other elements are arrays containing the result of the split() operation on classname.
To flatten this array, the flat(1) method is used. The filter() method needs to be applied to filter out undefined (empty string) classnames.
Upvotes: 0
Reputation: 464
Get all the classes & the unique ones in one dimension.
const allClasses = Array.from(new Set(document.querySelectorAll("*").map(el => el.classNames)));
const flatClasses = Array.from(new Set(allClasses.flat(1)))
Upvotes: -1
Reputation: 61
Piggybacking off of the one-liner from @user1679669 and @Nermin's answer using Set, you can get a list of all the classes on a page with this one-liner:
const allClasses = [...new Set([].concat(...[...document.querySelectorAll('*')].map(elt => [...elt.classList])))];
Upvotes: 6
Reputation: 935
const allClasses = Array.from(document.querySelectorAll('[class]')).flatMap(e => e.className.toString().split(/\s+/))
const classes = new Set()
allClasses.forEach(c => classes.add(c))
console.log(classes)
Get all the class names and split on space so for example, "child first" would become 'child' and 'first'. If you don't like this behaviour you can remove the toString and split functions.
Then add every class name to the set. There is no need to check for duplicates since the set does that for us. If you do want to store duplicates you can use a Map instead.
Upvotes: 6
Reputation:
Get all the elements in the document using querySelectorAll
, then loop through them, getting each one's class, breaking it apart on spaces, and adding new ones to an allClasses
array:
var allClasses = [];
var allElements = document.querySelectorAll('*');
for (var i = 0; i < allElements.length; i++) {
var classes = allElements[i].className.toString().split(/\s+/);
for (var j = 0; j < classes.length; j++) {
var cls = classes[j];
if (cls && allClasses.indexOf(cls) === -1)
allClasses.push(cls);
}
}
console.log(allClasses);
<div class="foo">
<div class="bar baz"></div>
</div>
To get the classnames in only one part of the document, specify that in the querySelectorAll
call:
var allElements = document.getElementById('my-elt').querySelectorAll('*');
Using ES6, we can write this more functionally as:
[].concat( // concatenate
...[... // an array of
document.querySelectorAll('*') // all elements
] .
map( // mapping each
elt => // element
[... // to the array of
elt.classList // its classes
]
)
);
Or, as a one liner:
[].concat(...[...document.querySelectorAll('*')].map(elt => [...elt.classList]));
Then you will want to apply uniq
to the result. You can write that yourself, or use Underscore's _.uniq
etc. Here's a simple one for use here:
function unique(array) {
var prev;
return array.sort().filter(e => e !== prev && (prev = e));
}
Upvotes: 17
Reputation: 2137
A one-liner that returns unique class names in alphabetical order, the query part based on @torazaburo's answer:
[].concat(...[...document.querySelectorAll('*')].map(e=>[...e.classList])).filter((d,i,a)=>a.indexOf(d)==i).sort()
Upvotes: 1
Reputation:
This is HTML:
<div id="oye">
<div class="pop"></div>
<div class="hop"></div>
<div class="bob"></div>
</div>
<p id="my"></p>
In Jquery, You will get array of all class name, Check below code
$(document).ready(function(){
var myclass = [];
var parent = $("#oye");
var divs = parent.children();
for(var i = 0; i < divs.length; i++){
myclass.push(divs[i].className)
}
//console.log(myclass);
var myclasses = myclass.join(', ');
$("#my").html(myclasses);
});
See Demo Here: https://codepen.io/ihemant360/pen/PzWJZP
Upvotes: 0
Reputation: 1579
I'd do something like the snippet below, it uses jQuery but that's just easier to read imo, a Javascript version wouldn't be much harder I'd assume.
Basically you want to get all of the nodes
, then add all of the unique classes to a list..
This is much harder to implement if you're looking for dynamic classes which may be applied with Javascript.
Nesting would require more insight as to how it should be performed, how to handle dupe classes but not dupe class arrays and similar..
If this get's downvoted because of the jQuery I'll be upset.
var classes = [];
$('body *:not(script)').each(function(){
_classes = $(this).attr('class') ? $(this).attr('class').split(' ') : []
_classes.forEach(function(entry){
if(classes.indexOf(entry) < 0){
classes.push(entry)
}
})
})
console.log(classes)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dog"></div>
<span class="dog cat"></span>
<div></div>
<blockquote class="bird"></blockquote>
Upvotes: 0