web-dev-qa-db-fra.com

Vérifiez si la classe existe quelque part dans le parent - Vanilla JS

J'ai vraiment du mal à voir comment faire cela. Je veux vérifier si une classe existe quelque part dans l'un des éléments parents d'un élément.

Je ne veux utiliser aucune bibliothèque, juste Vanilla JS.

Dans les exemples ci-dessous, la valeur true devrait être retournée si l'élément en question réside quelque part dans les enfants d'un élément avec "the-class" comme nom de classe.

Je pense que ce serait quelque chose comme ça avec jQuery:

if( $('#the-element').parents().hasClass('the-class') ) {
    return true;
}

Donc, cela retourne vrai:

<div>
    <div class="the-class">
        <div id="the-element"></div>
    </div>
</div>

Ainsi fait ceci:

<div class="the-class">
    <div>
        <div id="the-element"></div>
    </div>
</div>

... mais cela retourne faux:

<div>
    <div class="the-class">
    </div>
    <div id="the-element"></div>
</div>
19
user2143356

Vous devrez le faire récursivement:

// returns true if the element or one of its parents has the class classname
function hasSomeParentTheClass(element, classname) {
    if (element.className.split(' ').indexOf(classname)>=0) return true;
    return element.parentNode && hasSomeParentTheClass(element.parentNode, classname);
}

Démonstration (ouvrez la console pour voir true)

31
Denys Séguret

Le violon

Le code

function hasClass(element, className) {
  var regex = new RegExp('\\b' + className + '\\b');
  do {
    if (regex.exec(element.className)) {
      return true;
    }
    element = element.parentNode;
  } while (element);
  return false;
}

OR

function hasClass(element, className) {
  do {
    if (element.classList && element.classList.contains(className)) {
      return true;
    }
    element = element.parentNode;
  } while (element);
  return false;
}
5
James Newton

Je pense que if( $('#the-element').parents('.the-class').length ) est plus efficace, mais peut-être pas aussi lisible par l'homme; qui, avec querySelector dans l'image, pourrait être remplacé par la méthode suivante:

function hasParent(element, parentSelector) {
    var potentialParents = document.querySelectorAll(parentSelector);
    for(i in potentialParents) if(potentialParents[i].contains(element))
        return potentialParents[i];
    return false;
}

Cela vous donnerait la capacité de faire:

var Elm = document.getElementById('the-element');
if(hasParent(Elm, '.the-class')) return true;
2
Fardin K.

Vous pouvez utiliser some et contains pour obtenir le résultat suivant:

function hasParentWithMatchingSelector (target, selector) {
  return [...document.querySelectorAll(selector)].some(el =>
    el !== target && el.contains(target)
  )
}

// usage
hasParentWithMatchingSelector(myElement, '.some-class-name');
2
Fez Vrasta

Je suis d'accord avec la fonction que Denys Séguret a postée, elle est élégante et je l'aime bien. Je viens d’ajuster un peu cette fonction car si la classe spécifiée dans le paramètre n’est pas présente dans tout le DOM, elle échoue lorsque la récursion atteint l’objet document car il est vrai que nous contrôlons si l’élément a la noeud parent (dans la dernière ligne, et lorsque le document est l'élément, le noeud parent est null) mais avant d'exécuter la ligne précédente, et lorsque l'élément est le document, document.className est undefined et il échoue, le contrôle doit donc être déplacé jusqu'au sommet.

function hasSomeParentTheClass(element, classname) {
    //
    // If we are here we didn't find the searched class in any parents node
    //
    if (!element.parentNode) return false;
    //
    // If the current node has the class return true, otherwise we will search
    // it in the parent node
    //
    if (element.className.split(' ').indexOf(classname)>=0) return true;
    return hasSomeParentTheClass(element.parentNode, classname);
}
2
AndreaScn

Mon exemple pour Vanilla JS, c’est l’utilisation d’un équivalent vanille de parents() de jQuery

var htmlElement = <htmlElement>,
    parents = [],
    classExist;
while (htmlElement = htmlElement.parentNode.closest(<parentSelector>)) {
    parents.Push(htmlElement);
}
classExist = (parents > 0);

Donc, votre sélecteur juste pour être un .className

Et juste vérifier si le parent est> 0

0
Bruno Lesieur