Polyfill for getElementByClassName()

Write a custom function to find all the elements with the given class in the DOM. Simply put, write the polyfill for the getElementByClassName();

Example

Input:
<div class='a' id="root">
  <div class='b' id='b-1'>
    <div class='a' id='a-2'>
      <div class='d' id='d-1'></div>
    </div>
    <div class='c' id='c-1'>
      <div class='a' id='a-3'>
        <div class='d' id='d-2'></div>
      </div>
    </div>
  </div>
</div>

findByClass('a');

Output:
[<div class="a" id="root">
  <div class="b" id="b-1">
    <div class="a" id="a-2">
      <div class="d" id="d-1"></div>
    </div>
    <div class="c" id="c-1">
      <div class="a" id="a-3">
        <div class="d" id="d-2"></div>
      </div>
    </div>
  </div>
</div>,
<div class="a" id="a-2">
      <div class="d" id="d-1"></div>
</div>,
<div class="a" id="a-3">
       <div class="d" id="d-2"></div>
</div>
]

The approach to solving this is straightforward, As a DOM element can have multiple classes to it, all we have to do is start from the body or the root element and check if the current node’s classlist has the class or not.

If it has it, then push the node in the result. After that traverse all the children of the node and for each child check if they have the class in their classList or not.

We can recursively call the same function for each child and it will call their children and so on and perform the test and return the result. This traversing pattern is known as DFS (Depth First Search).

function findByClass(class) {
  // get the root element,
  // you can start from the body
  const root = document.body;
  
  // helper function to perform a search using dfs
  function search(node) {
    // store the result
    let result = [];
    
    // if the class name is present in the class list of the element
    // add the element in the result
    if(node.classList.contains(class)) {
       result.push(node);
    }
   
    // for all the children of the element 
    // recursively search and check if the class is present
    for (const element of node.children) {
      // recursively search
      const res = search(element);
      
      // add the result from the recursive 
      // search to the actual result
      result = result.concat(res);
    }
    
    // return the result
    return result;
  }
  
  // initiate the search and return the result
  return search(root);
}
Input:
<div class='a' id="root">
  <div class='b' id='b-1'>
    <div class='a' id='a-2'>
      <div class='d' id='d-1'></div>
    </div>
    <div class='c' id='c-1'>
      <div class='a' id='a-3'>
        <div class='d' id='d-2'></div>
      </div>
    </div>
  </div>
</div>

console.log(findByClass('a'));

Output:
[<div class="a" id="root">
  <div class="b" id="b-1">
    <div class="a" id="a-2">
      <div class="d" id="d-1"></div>
    </div>
    <div class="c" id="c-1">
      <div class="a" id="a-3">
        <div class="d" id="d-2"></div>
      </div>
    </div>
  </div>
</div>,
<div class="a" id="a-2">
      <div class="d" id="d-1"></div>
</div>,
<div class="a" id="a-3">
       <div class="d" id="d-2"></div>
</div>
]