B Hull
B Hull

Reputation: 3223

Vanilla javascript check if element or ancestor has class

Hello this code gets tells me if current element has class.

e.srcElement.className.indexOf('thisClass') === 0  

How do i also check if element or any of its parents have the class?

Upvotes: 3

Views: 8442

Answers (5)

Ludder
Ludder

Reputation: 2733

Nowadays one can use the widely supported JavaScript closest method.

const parentHasClass = element.closest('.thisClass');

Upvotes: 14

TachikomaGT
TachikomaGT

Reputation: 1009

I can offer to use next methods:

function hasClass(element, className) {
    return !(!className || !element || !element.className 
    || !element.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)')));
}

function parentByClass(childElement, className) {
    if (!childElement || childElement === document) {
        return null;
    } else if (hasClass(childElement, className)) {
        return childElement;
    } else {
        return parentByClass(childElement.parentNode, className)
    }
}

function hasClassInTree(element, className) {
    return hasClass(element, className) || parentByClass(element, className)
}

So in you case condition will be

if (hasClassInTree(e.srcElement, 'thisClass')) { ... }

Upvotes: 1

Dmitri Pavlutin
Dmitri Pavlutin

Reputation: 19060

Using the parentNode of an element, it's possible to go through the parents list.
Use the following function:

function elementOrAncestorHasClass(element, className) {
  if (!element || element.length === 0) {
    return false;
  }
  var parent = element;
  do {
    if (parent === document) {
      break;
    }
    if (parent.className.indexOf(className) >= 0) {
      return true;
    }
  } while (parent = parent.parentNode);
  return false;
}

This fiddle shows the function in action.

Upvotes: 6

Yevgeniy Goyfman
Yevgeniy Goyfman

Reputation: 492

May be its easier to find all the elements that have the class, and check if any of them contain the current node (not tested code):

   function checkParentClass(e,className){
      var nodesWithClass =document.getElementsByClassName("className");

      var index =0;
      var found = false;

      while(index< nodesWithClass.length && !found){
         if (nodesWithClass[index].contains(e))
         {
            found = true;
         }
         index++;
      }

      return found;
    }

Upvotes: -1

Josh Beam
Josh Beam

Reputation: 19772

You just need to traverse the DOM. To go one parent up, use parentNode.

Do traverse infinitely upwards, you'll need to use a loop:

for(var i = 0; i < nodes.length; i++) {
  // check if each parentNode has the class
}

It's a tedious process. That's why libraries like jQuery exist for the sole purpose of DOM traversal/manipulation.

Upvotes: 1

Related Questions