Eu apenas tive que compartilhar 'meu'.
Embora conceitualmente seja o mesmo que a resposta do Asaph (beneficiando da mesma compatibilidade entre navegadores, até o IE6), é muito menor e é útil quando o tamanho é alto e / ou quando não é necessário com tanta frequência.
function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
while((c=c.parentNode)&&c!==p);
return !!c;
}
..ou como one-liner ( apenas 64 caracteres !):
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
e jsfiddle aqui .
Uso:
childOf(child, parent) retorna booleanotrue| false.
Explicação:
while avalia enquanto a condição while for avaliadatrue.
O&&operador (AND) retorna esse booleano verdadeiro / falso após avaliar o lado esquerdo e o lado direito, mas apenas se o lado esquerdo for verdadeiro ( left-hand && right-hand) .
O lado esquerdo (de &&) é: (c=c.parentNode).
Isso primeiro atribuirá o parentNodede ae, cem cseguida, o operador AND avaliará o resultado ccomo um booleano.
Como parentNoderetorna nullse não houver nenhum pai sobrando e nullfor convertido para false, o loop while será interrompido corretamente quando não houver mais pais.
O lado direito (de &&) é: c!==p.
O !==operador de comparação é ' não exatamente igual a'. Portanto, se o pai da criança não é o pai (você especificou), ele avalia true, mas se o pai da criança é o pai, ele avalia false.
Portanto, se for c!==p avaliado como falso, o &&operador retornará falsequando a condição while e o loop while forem interrompidos. (Observe que não há necessidade de um corpo while e o ;ponto e vírgula de fechamento é necessário.)
Portanto, quando o loop while termina, cé um nó (não null) quando ele encontra um pai OU null(quando o loop é executado até o final sem encontrar uma correspondência).
Portanto, simplesmente returnesse fato (convertido como valor booleano, em vez de nó) com return !!c;:: the !( NOToperator) inverte um valor booleano ( truetorna false- se e vice-versa).
!cconverte c(nó ou nulo) em um booleano antes de poder inverter esse valor. Portanto, adicionar um segundo !( !!c) converte esse falso de volta em verdadeiro (e é por isso que um duplo !!é frequentemente usado para 'converter qualquer coisa em booleano').
Extra:
O corpo / carga útil da função é tão pequeno que, dependendo do caso (como quando não é usado frequentemente e aparece apenas uma vez no código), pode-se até omitir a função (quebra automática) e usar o loop 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
}
ao invés de:
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
}