7

I've been thinking about why we cannot do this in javascript.

document.getElementsByClassName('class1').getElementsByClassName('class2')

This will not work, because the first getElementsByClassName call will give us an HTMLCollection, which doesn't have getElementsByClassName defined on it. Why is this? This would be a great function to use in this way, since it would let you get elements based on them having multiple different classes, not just one.

Is there any way to:

  1. Get elements by class name in HTMLCollection
  2. Get elements by multiple class names
Pointy
  • 405,095
  • 59
  • 585
  • 614
Sahand
  • 7,980
  • 23
  • 69
  • 137
  • 3
    How about `document.querySelectorAll(".class1.class2")` – Pointy Jan 03 '18 at 16:11
  • That's a decent solution. However, I think the classes should be separated by a comma, right? – Sahand Jan 03 '18 at 16:13
  • 2
    Problem is HTML Collection does not have methods so either you would need to loop over each one individually and filter them and build your own collection or use a better method `querySelectorAll` – epascarello Jan 03 '18 at 16:13
  • if you want to make it a little more complicated for yourself: Array.from( document.getElementsByClassName('class1')).filter((item)=>{return Array.from(item.classList).includes('class2')}) – LShapz Jan 03 '18 at 16:14
  • No, selector syntax for an element with two classes is to have them next to each other with no spaces. Comma would mean either "class1" or "class2", which is not the same as **both** "class1" and "class2". – Pointy Jan 03 '18 at 16:14
  • 3
    @Sandi, no the comma would be this OR that, not AND. – epascarello Jan 03 '18 at 16:14
  • You can use for multiple class name on one element like this: `document.getElementsByClassName('container _full')` (separated with one space) – golddragon007 Jan 03 '18 at 16:15

2 Answers2

6

Get by multiple class names:

document.querySelector('.someclass.otherclass'); // get first element that matches
document.querySelectorAll('.someclass.otherclass'); //get all elements that match

You can querySelector* any DOM element, not just document, in order to search in it.

Get by class name in HTMLCollection

[].filter.call(
    htmlCollection, element => [].includes.call(elements.classList, 'someclassname')
)

Neither HTMLCollection nor .classList are arrays, only array-like objects, hence the need for .call.

kon.simeonov
  • 234
  • 2
  • 6
1
  1. Get elements by class name in HTMLCollection :

    HTMLCollection.prototype.forEach = Array.prototype.forEach;
    
    HTMLCollection.prototype.getElementsByClassName = function( name ){
        var all = [];
        this.forEach( function( el ){
             if( el )
                 all.concat( el.getElementsByClassName( name ) );
        });
        return all;
    }
    
  2. Get elements by multiple class names :

    document.querySelectorAll('.class1.class2');
    

Please use the second for better performance.

mshwf
  • 7,009
  • 12
  • 59
  • 133
karkael
  • 431
  • 2
  • 9