Como posso verificar se um elemento DOM é filho de outro elemento DOM? Existem métodos integrados para isso? Por exemplo, algo como:
if (element1.hasDescendant(element2))
ou
if (element2.hasParent(element1))
Se não, então alguma idéia de como fazer isso? Ele também precisa ser entre navegadores. Devo também mencionar que a criança pode estar aninhada muitos níveis abaixo do pai.
javascript
dom
AJ.
fonte
fonte
Respostas:
Atualização: Agora existe uma maneira nativa de conseguir isso.
Node.contains()
. Mencionado no comentário e respostas abaixo também.Resposta antiga:
Usar a
parentNode
propriedade deve funcionar. Também é bastante seguro do ponto de vista entre navegadores. Se o relacionamento é conhecido por ter um nível de profundidade, você pode verificá-lo simplesmente:Se o filho puder ser aninhado arbitrariamente no fundo do pai, você poderá usar uma função semelhante à seguinte para testar o relacionamento:
fonte
Node.contains
(sem página caniuse embora)Node.contains
? :)Você deveria usar
Node.contains
, pois agora é padrão e está disponível em todos os navegadores.https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
fonte
var parent = document.getElementById('menu'); var allElements = document.getElementsByTagName('a'); if (parent.contains(allElements[i]) { alert('Link is inside meni'); }
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.
..ou como one-liner ( apenas 64 caracteres !):
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
parentNode
de ae,c
emc
seguida, o operador AND avaliará o resultadoc
como um booleano.Como
parentNode
retornanull
se não houver nenhum pai sobrando enull
for convertido parafalse
, 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 avaliatrue
, mas se o pai da criança é o pai, ele avaliafalse
.Portanto, se for
c!==p
avaliado como falso, o&&
operador retornaráfalse
quando 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ãonull
) quando ele encontra um pai OUnull
(quando o loop é executado até o final sem encontrar uma correspondência).Portanto, simplesmente
return
esse fato (convertido como valor booleano, em vez de nó) comreturn !!c;
:: the!
(NOT
operator) inverte um valor booleano (true
tornafalse
- se e vice-versa).!c
convertec
(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:
ao invés de:
fonte
!==
) pode melhorar a velocidade, deixando claro para o compilador que pode pular as etapas de verificação de tipo e conversão implícita opcionais que ocorreriam em uma comparação de igualdade frouxa, melhorando assim a velocidade (descrevendo com mais precisão o que quer que aconteça, o que também é benéfico para o programador). Também me lembro de quando escrevi isso, que apenas a comparação frouxa (!=
) era muito suscetível a erros ou não funcionava em alguns navegadores mais antigos (suspeito que fosse no IE6, mas esqueci )Outra solução que não foi mencionada:
Exemplo Aqui
Não importa se o elemento é um filho direto, ele funcionará a qualquer profundidade.
Como alternativa, usando o
.contains()
método :Exemplo Aqui
fonte
Dê uma olhada no Node # compareDocumentPosition .
Outros relacionamentos incluem
DOCUMENT_POSITION_DISCONNECTED
,DOCUMENT_POSITION_PRECEDING
eDOCUMENT_POSITION_FOLLOWING
.Não suportado no IE <= 8.
fonte
Você pode usar o método contains
var result = parent.contains(child);
ou você pode tentar usar compareDocumentPosition ()
var result = nodeA.compareDocumentPosition(nodeB);
O último é mais poderoso: retorna uma máscara de bit como resultado.
fonte
Me deparei com um maravilhoso pedaço de código para verificar se um elemento é ou não filho de outro elemento. Eu tenho que usar isso porque o IE não suporta o
.contains
método elemento. Espero que isso ajude outras pessoas também.Abaixo está a função:
fonte
tente este:
fonte
Recentemente, deparei-me com esta função que pode fazer:
Node.compareDocumentPosition ()
fonte