Wie kann ich überprüfen, ob ein DOM-Element einem anderen DOM-Element untergeordnet ist? Gibt es dafür eingebaute Methoden? Zum Beispiel so etwas wie:
if (element1.hasDescendant(element2))
oder
if (element2.hasParent(element1))
Wenn nicht, dann irgendwelche Ideen, wie das geht? Es muss auch browserübergreifend sein. Ich sollte auch erwähnen, dass das Kind viele Ebenen unterhalb des Elternteils verschachtelt sein könnte.
javascript
dom
AJ.
quelle
quelle
Antworten:
Update: Es gibt jetzt einen nativen Weg, um dies zu erreichen.
Node.contains()
. Erwähnt im Kommentar und unten auch Antworten.Alte Antwort:
Die Verwendung der
parentNode
Eigenschaft sollte funktionieren. Es ist auch aus browserübergreifender Sicht ziemlich sicher. Wenn bekannt ist, dass die Beziehung eine Ebene tief ist, können Sie sie einfach überprüfen:Wenn das Kind beliebig tief im Elternteil verschachtelt werden kann, können Sie eine ähnliche Funktion wie die folgende verwenden, um die Beziehung zu testen:
quelle
Node.contains
(keine caniuse Seite obwohl)Node.contains
? :)Sie sollten verwenden
Node.contains
, da es jetzt Standard ist und in allen Browsern verfügbar ist.https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
quelle
var parent = document.getElementById('menu'); var allElements = document.getElementsByTagName('a'); if (parent.contains(allElements[i]) { alert('Link is inside meni'); }
Ich musste nur 'meine' teilen.
Obwohl es konzeptionell mit der Antwort von Asaph identisch ist (mit der gleichen browserübergreifenden Kompatibilität, sogar mit IE6), ist es viel kleiner und praktisch, wenn die Größe knapp ist und / oder wenn es nicht so oft benötigt wird.
..oder als Einzeiler ( nur 64 Zeichen !):
und jsfiddle hier .
Verwendung:
childOf(child, parent)
Gibt booleantrue
| zurückfalse
.Erläuterung: Wird
while
ausgewertet, solange die while-Bedingung ausgewertet wirdtrue
.Der
&&
Operator (AND) gibt diesen booleschen Wert true / false zurück, nachdem die linke und die rechte Seite ausgewertet wurden, jedoch nur, wenn die linke Seite true (left-hand && right-hand
) war. .Die linke Seite (von
&&
) ist :(c=c.parentNode)
.Dadurch wird zuerst das
parentNode
vonc
bis zugewiesen ,c
und dann bewertet der AND-Operator das Ergebnisc
als Booleschen Wert.Da
parentNode
zurückgegeben wird,null
wenn kein übergeordnetes Element mehr vorhanden ist und innull
das konvertiert wird,false
wird die while-Schleife korrekt gestoppt, wenn keine übergeordneten Elemente mehr vorhanden sind.Die rechte Seite (von
&&
) ist :c!==p
.Der
!==
Vergleichsoperator ist ' nicht genau gleich'. Wenn also das Elternteil des Kindes nicht das Elternteil ist (das Sie angegeben haben), wird es ausgewertettrue
, aber wenn das Elternteil des Kindes das Elternteil ist, wird es ausgewertetfalse
.Also , wenn
c!==p
das Ergebnis falsch, dann werden die&&
Bediener kehrtfalse
als while-Zustand und die while-Schleife beendet. (Beachten Sie, dass ein while-body und das Schließen nicht erforderlich sind;
erforderlich ist Semikolon erforderlich ist.)Wenn die while-Schleife endet,
c
ist sie entweder ein Knoten (nichtnull
), wenn sie ein übergeordnetes Element gefunden hat, oder sie ist esnull
(wenn die Schleife bis zum Ende durchgegangen ist, ohne eine Übereinstimmung zu finden).Also einfach
return
diese Tatsache (konvertiert als boolescher Wert anstelle des Knotens) mit ::return !!c;
der!
(NOT
Operator) invertiert einen booleschen Wert (true
wirdfalse
und umgekehrt).!c
konvertiertc
(Knoten oder Null) in einen Booleschen Wert, bevor dieser Wert invertiert werden kann. Wenn Sie also ein second!
(!!c
) hinzufügen, wird dieses false wieder in true konvertiert (weshalb ein Double!!
häufig verwendet wird, um "alles in Boolesche Werte umzuwandeln").Extra:
Die Körper / Nutzlast - Funktion ist so klein , dass im Fall abhängig (wie wenn es nicht oft verwendet wird , und erscheint nur einmal im Code), einer konnte sogar die Funktion (Verpackung) auslassen und benutzen Sie einfach die while-Schleife:
anstatt:
quelle
!==
) kann die Geschwindigkeit verbessern, indem dem Compiler klar gemacht wird, dass er die Typprüfung und optionale implizite Konvertierungsschritte überspringen kann, die bei einem losen Gleichheitsvergleich auftreten würden, wodurch die Geschwindigkeit verbessert wird (indem genauer beschrieben wird, was wir tun passieren wollen, was auch für den Programmierer von Vorteil ist). Ich erinnere mich auch daran, als ich dies schrieb, dass nur der lose Vergleich (!=
) entweder sehr fehleranfällig war oder in einigen älteren Browsern überhaupt nicht funktionierte (ich vermute, dass es in IE6 war, aber ich habe es vergessen ).Eine andere Lösung, die nicht erwähnt wurde:
Beispiel hier
Es spielt keine Rolle, ob das Element ein direktes untergeordnetes Element ist, es funktioniert in jeder Tiefe.
Alternativ mit der
.contains()
Methode :Beispiel hier
quelle
Schauen Sie sich Node # compareDocumentPosition an .
Andere Beziehungen sind
DOCUMENT_POSITION_DISCONNECTED
,DOCUMENT_POSITION_PRECEDING
undDOCUMENT_POSITION_FOLLOWING
.Wird im IE <= 8 nicht unterstützt.
quelle
Sie können die Methode includes verwenden
var result = parent.contains(child);
oder Sie können versuchen, compareDocumentPosition () zu verwenden
var result = nodeA.compareDocumentPosition(nodeB);
Der letzte ist leistungsfähiger: Als Ergebnis wird eine Bitmaske zurückgegeben.
quelle
Ich bin auf einen wunderbaren Code gestoßen, um zu überprüfen, ob ein Element ein Kind eines anderen Elements ist oder nicht. Ich muss dies verwenden, da der IE die
.contains
Elementmethode nicht unterstützt . Hoffe, das wird auch anderen helfen.Unten ist die Funktion:
quelle
Probier diese:
quelle
Ich bin kürzlich auf diese Funktion gestoßen, die Folgendes bewirken könnte:
Node.compareDocumentPosition ()
quelle