Ho dovuto solo condividere il "mio".
Sebbene concettualmente identica alla risposta di Asaph (che beneficia della stessa compatibilità cross-browser, anche IE6), è molto più piccola e risulta utile quando le dimensioni sono un premio e / o quando non è necessario così spesso.
function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
while((c=c.parentNode)&&c!==p);
return !!c;
}
..o come one-liner ( solo 64 caratteri !):
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
e jsfiddle qui .
Utilizzo:
childOf(child, parent) restituisce valore booleanotrue| false.
Spiegazione:
while valuta finché dura la condizione whiletrue.
L'&&operatore (AND) restituisce questo vero / falso booleano dopo aver valutato il lato sinistro e il lato destro, ma solo se il lato sinistro era true ( left-hand && right-hand) .
Il lato sinistro (di &&) è: (c=c.parentNode).
Questo assegnerà prima parentNodedi tutto ca, cquindi l'operatore AND valuterà il risultato ccome un valore booleano.
Poiché parentNoderitorna nullse non è rimasto alcun genitore e nullviene convertito in false, il ciclo while si interromperà correttamente quando non ci sono più genitori.
Il lato destro (di &&) è: c!==p.
L' !==operatore di confronto è " non esattamente uguale a". Quindi, se il genitore del bambino non è il genitore (specificato) true, ma se il genitore del bambino è il genitore, lo valuta false.
Pertanto, se restituisce c!==pfalse, l' &&operatore ritorna falsecome condizione while e il ciclo while si interrompe. (Nota che non è necessario un while-body ed ;è richiesto il punto e virgola di chiusura .)
Quindi, quando il ciclo while termina, cè o un nodo (non null) quando ha trovato un padre O lo è null(quando il ciclo ha funzionato fino alla fine senza trovare una corrispondenza).
Quindi semplicemente returnquel fatto (convertito in valore booleano, invece del nodo) con return !!c;:: l' operatore !( NOToperatore) inverte un valore booleano ( truediventa falsee viceversa).
!cconverte c(nodo o null) in un valore booleano prima che possa invertire tale valore. Così l'aggiunta di un secondo !( !!c) converte questa falsa torna a true (che è il motivo per cui una doppia !!viene spesso usata per 'convertire qualsiasi cosa per booleana').
Extra:
il corpo / payload della funzione è così piccolo che, a seconda del caso (come quando non viene usato spesso e appare solo una volta nel codice), si potrebbe persino omettere la funzione (wrapping) e usare solo il ciclo while:
var a=document.getElementById('child'),
b=document.getElementById('parent'),
c;
c=a; while((c=c.parentNode)&&c!==b); //c=!!c;
if(!!c){ //`if(c)` if `c=!!c;` was used after while-loop above
//do stuff
}
invece di:
var a=document.getElementById('child'),
b=document.getElementById('parent'),
c;
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
c=childOf(a, b);
if(c){
//do stuff
}