2013-05-31 4 views
11

Ich habe wirklich Mühe zu sehen, wie dies zu tun ist. Ich möchte überprüfen, ob eine Klasse irgendwo in einem der Elternelemente eines Elements vorhanden ist.Überprüfen Sie, ob die Klasse irgendwo in Eltern existiert - Vanille JS

Ich möchte keine Bibliothek verwenden, nur Vanille JS.

In den folgenden Beispielen sollte true zurückgegeben werden, wenn sich das fragliche Element irgendwo in den childs eines Elements mit der Klasse "the-class" befindet.

denke ich, es so etwas wie dies mit jQuery wäre:

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

Also das gibt true zurück:

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

So tut dies:

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

... aber das gibt false zurück:

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

jquery Mit diesem mit engsten wäre (‘theClass.) .length –

+0

Haben Sie einen Code, um zu zeigen, was Sie versucht haben, damit wir sehen können, wo Sie Hilfe benötigen? –

+0

Sie möchten also sehen, ob einer der Vorfahren oder Geschwister von Vorfahren einen bestimmten Klassennamen hat? –

Antwort

23

Sie werden es rekursiv zu tun haben:

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

Demonstration (die Konsole öffnen true zu sehen)

+0

Perfekt. Vielen Dank. – user2143356

+1

dies schlägt fehl, wenn ein Elternteil keine Klasse hat –

+0

@ Carl91 Wenn ein Element keine Klasse hat, ist 'className'' '' '. –

4

Die fiddle

Der 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; 
} 
2

Ich glaube, if($('#the-element').parents('.the-class').length) effizienter zu sein, aber vielleicht nicht so gut lesbar; , die mit querySelector im Bild, könnte mit dem folgende Verfahren ersetzt:

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

Das würden Sie die Möglichkeit, zu tun:

var elm = document.getElementById('the-element'); 
if(hasParent(elm, '.the-class')) return true; 
+0

Ich hatte das gleiche Problem und ich kam mit dieser Lösung, also dachte ich, ich würde es hier für andere, die mit diesem Problem konfrontiert sind, posten. – Fardin

+0

Warum ist $ effizienter? – SuperUberDuper

+0

@SuperUberDuper Ich habe nicht vorgeschlagen, dass jQuery effizienter ist als der einzelne Vanilla-Code, wenn Sie das fragen. Ich vermutete, dass die Verwendung eines Selektors mit "Eltern" zu einer weniger Schleife führen kann, verglichen mit der jq-Linie von OP. Schlechte Phrasierung, nicht wahr? – Fardin

0

Da ID muss eindeutig sein auf Dokumentkontext, Sie verwenden könnte nur statt:

return !!document.querySelector('.the-class #the-element'); 

Wenn Sie Element selbst aufnehmen möchten, können Sie verwenden:

return !!document.querySelector('.the-class #the-element, #the-element.the-class'); 
0

Mein Beispiel für Vanilla JS, dann ist es

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

So Ihre Wähler ein .className

zu sein nur ein Vanille-Äquivalent parents() von jQuery verwenden und nur überprüfen, ob Eltern> 0

2

Ich bin ok mit der Funktion, die Denys Séguret gepostet hat, sieht es elegant aus und ich mag es. Ich habe nur ein bisschen diese Funktion optimiert, da, wenn die im Parameter angegebene Klasse nicht im gesamten DOM vorhanden ist, es fehlschlägt, wenn die Rekursion das Dokumentobjekt erreicht, weil es wahr ist, dass wir kontrollieren, ob das Element den Elternknoten hat die letzte Zeile, und wenn das Dokument das Element ist der Elternknoten ist Null), aber bevor wir die vorherige Zeile ausführen, und wenn das Element das Dokument ist document.className ist undefined und es schlägt fehl, also muss das Steuerelement an die Spitze verschoben werden.

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

Sie some verwenden können und contains das Ergebnis zu erreichen:

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

// usage 
hasParentWithMatchingSelector(myElement, '.some-class-name'); 
+0

Das ist wirklich clever .. braucht nur eine Korrektur, weil 'el.contains (el) true zurückgibt. Also sollten wir es wie folgt umschreiben: 'el! == target && el.contains (target)' – chrislopresto

+0

gefixed danke ... –

0

Hier ist eine einfache genug Lösung

if ($elem.parents('.the-class').length) { 
    return true 
} 
Verwandte Themen