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>
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
)
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;
}
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;
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');
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);
}
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