Como encontrar os pais, irmãos e filhos de um elemento usando o JavaScript DOM

Recentemente, eu estava trabalhando em um projeto que exigia que eu adicionasse uma classe a todos os irmãos de um elemento se um dos irmãos tivesse essa classe. Da mesma forma, fui obrigado a mostrar um pop-up se um ancestral do elemento atual tivesse uma classe específica. Percorrer para cima, para baixo ou para os lados em um DOM torna-se importante em muitas situações quando você está fazendo desenvolvimento web.

Neste tutorial, mostrarei como encontrar os pais, filhos ou irmãos de um elemento usando JavaScript puro sem a necessidade de nenhuma biblioteca auxiliar.

O seguinte HTML será nossa referência para este tutorial:

1
2
   class="first-item"> class="first-para">Elephants are the  class="hlt">largest existing land animals.

3
  
  • Elephant skin is class="important">2.5cm thick on the back and parts of the head.

  • 4
       class="last-item">About 60% of an Elephant's weight is borne by its front legs.

    5
    
    

    Ele contém três itens de lista, cada um envolvendo um parágrafo. Cada parágrafo contém vários span elementos. O primeiro item da lista contém um span tag que tem a classe hlt aplicado a ele. Usaremos isso com bastante frequência em nosso tutorial.

    Encontrar o pai de um elemento

    Se você estiver realmente procurando pelo ancestral imediato ou pai de um elemento, basta verificar o valor do parentNode ou parentElement propriedade. Depois de ter o nó ou elemento pai, você pode fazer inspeções adicionais com a ajuda de propriedades como classList ou textContent como mostrado abaixo.

    1
    let hlt_span = document.querySelector(".hlt");
    
    2
    
    
    3
    // Output: 

    Elephants are the largest existing land animals.

    4
    console.log(hlt_span.parentElement);
    
    5
    
    
    6
    // Output: DOMTokenList [ "first-para" ]
    
    
    7
    console.log(hlt_span.parentElement.classList);
    
    8
    
    
    9
    // Output: Elephants are the largest existing land animals.
    
    
    10
    console.log(hlt_span.parentElement.textContent);
    

    Encontrar ancestrais do elemento atual

    Você pode usar o closest() método se você quiser percorrer o elemento atual, bem como todos os seus ancestrais até a raiz do documento para localizar um elemento específico que corresponda ao seletor especificado como um argumento para esse método.

    O closest() método irá retornar null se não houver ancestrais que correspondam ao seletor passado. Você também receberá SyntaxError se você não quiser um seletor CSS válido como argumento.

    Aqui está um exemplo:

    1
    let hlt_span = document.querySelector(".hlt");
    
    2
    
    
    3
    // Output: 
  • 4
    console.log(hlt_span.closest("li.first-item"));
    
    5
    
    
    6
    // Output: null
    
    
    7
    console.log(hlt_span.closest("li.last-item"));
    

    Você pode ver no exemplo acima que embora nossa marcação contenha um elemento de lista com classe last-itemnão é um ancestral do nosso span marcar com classe hlt. Portanto, uma chamada para closest() do nosso elemento span retorna null.

    Por outro lado, uma chamada para closest() com li.first-item como seletor nos devolve o primeiro item da lista.

    Encontre os Filhos do Elemento Atual

    Assim como o parentNode ou parentElement propriedade, existem propriedades semelhantes chamadas childNodes e children que você pode usar para obter informações sobre diferentes elementos filhos. A principal diferença entre esses dois é que childNodes retornará elementos, texto e nós de comentários. Por outro lado, children só retornará os nós de elemento enquanto ignora os nós de texto ou comentário.

    1
    let first_item = document.querySelector("li.first-item p");
    
    2
    
    
    3
    // Output: NodeList(4) [ span, #text, span.hlt, #text ]
    
    
    4
    console.log(first_item.childNodes);
    
    5
    
    
    6
    // Output: HTMLCollection { 0: span, 1: span.hlt, length: 2 }
    
    
    7
    console.log(first_item.children);
    

    Digamos que você esteja procurando uma criança span elemento com classe hlt dentro do primeiro item da lista. Você pode iterar sobre todos os elementos filho e, em seguida, usar o classList propriedade e sua contains() para ver se algum deles tem a classe especificada.

    1
    let first_item = document.querySelector("li.first-item p");
    
    2
    
    
    3
    // Output: largest
    
    
    4
    for(child of first_item.children) {
    
    5
      if(child.classList.contains("hlt")){
    
    6
        console.log(child);
    
    7
      }
    
    8
    }
    

    Encontre um descendente do elemento atual

    Você provavelmente já está familiarizado com o querySelector() e querySelectorAll() métodos que podem ser chamados no Document objeto. Esses métodos permitem localizar qualquer elemento no documento que corresponda ao seletor especificado.

    Os mesmos métodos também são definidos para o objeto Element e permitem que você encontre qualquer elemento que seja descendente do elemento chamador e corresponda ao seletor especificado.

    1
    let list = document.querySelector("ol");
    
    2
    let list_spans = list.querySelectorAll("span");
    
    3
    
    
    4
    // Output: 9
    
    
    5
    console.log(list_spans.length);
    
    6
    
    
    7
    // Output: 2.5cm thick
    
    
    8
    for(span of list_spans) {
    
    9
      if(span.classList.contains("important")){
    
    10
        console.log(span);
    
    11
      }
    
    12
    }
    

    havia nove span tags em nossa marcação original que eram descendentes da lista ordenada. Você pode ver no código acima que todos eles estavam presentes em list_spans verificando se o valor retornado pelo length propriedade é de fato 9.

    Nós iteramos sobre todos esses span tags para encontrar uma que tenha a classe important aplicado a ele.

    Você também pode usar querySelector() e querySelectorAll() para encontrar os descendentes diretos ou filhos do elemento de chamada passando :scope > selector como o valor do seletor para esses métodos. Aqui está um exemplo:

    1
    let first_item = document.querySelector("p");
    
    2
    
    
    3
    let direct_spans = first_item.querySelectorAll(":scope > span");
    
    4
    
    
    5
    // Output: largest
    
    
    6
    for(span of direct_spans) {
    
    7
      if(span.classList.contains("hlt")){
    
    8
        console.log(span);
    
    9
      }
    
    10
    }
    

    Encontre os próximos e anteriores irmãos

    Encontrar o próximo e o anterior irmão de um elemento é fácil quando você tem uma referência ao seu nó. O próximo irmão pode ser encontrado usando o nextSibling propriedade e o irmão anterior podem ser encontrados usando o previousSibling propriedade. Você deve observar que ambas as propriedades também retornarão quaisquer nós de texto ou nós de comentários existentes.

    Se você estiver interessado apenas em encontrar os nós do elemento seguinte ou anterior, considere usar o nextElementSibling e previousElementSibling propriedade. aqui estão alguns exemplos:

    1
    let important = document.querySelector(".important");
    
    2
    
    
    3
    // Output: #text " skin is "
    
    
    4
    console.log(important.previousSibling);
    
    5
    
    
    6
    // Output: #text " on the back and "
    
    
    7
    console.log(important.nextSibling);
    
    8
    
    
    9
    // Output: Elephant
    
    
    10
    console.log(important.previousElementSibling);
    
    11
    
    
    12
    // Output: parts
    
    
    13
    console.log(important.nextElementSibling);
    

    Encontre todos os irmãos de um elemento

    Uma instância de nó também possui algumas outras propriedades úteis, como o parentElement propriedade que retorna o elemento pai do nó DOM atual. Depois de ter o elemento pai, você pode usar seu children imóvel para morar HTMLCollection de todos os seus elementos filhos.

    Depois de ter todos os elementos filhos, basta iterar sobre eles para excluir o elemento cujos irmãos queremos encontrar e armazenar todos os outros em uma matriz conforme mostrado abaixo.

    1
    let important = document.querySelector(".important");
    
    2
    let all_children = important.parentElement.children;
    
    3
    let siblings = [];
    
    4
    
    
    5
    // HTMLCollection { 0: span, 1: span.important, 2: span, 3: span, length: 4 }
    
    
    6
    console.log(all_children);
    
    7
    
    
    8
    for(child of all_children) {
    
    9
      if(child != important) {
    
    10
        siblings.push(child);
    
    11
      }
    
    12
    }
    
    13
    
    
    14
    // [Elephant, parts, head]
    
    
    15
    console.log(siblings);
    

    Encontre todos os irmãos anteriores de um elemento

    Nesta e na próxima seção, aprenderemos como obter todos os irmãos anteriores ou posteriores de um elemento em JavaScript. Eu gostaria de usar uma lista ordenada para esses exemplos com os nomes de algumas pessoas aleatórias. Aqui está nossa marcação:

    1
     class="people">
    
    2
      
  • Adam
  • 3
      
  • Charles
  • 4
      
  • John
  • 5
      
  • Amanda
  • 6
      
  • Emma
  • 7
      
  • Emily
  • 8
       class="lawyer">Saul Goodman
    
    9
      
  • Hank
  • 10
      
  • Walter
  • 11
      
  • Skyler
  • 12
      
  • Jesse
  • 13
    
    

    Nosso objetivo aqui é percorrer a lista de pessoas e encontrar todos os irmãos anteriores de nosso elemento de lista com a classe lawyer.

    O truque aqui é obter uma referência ao elemento advogado e continuar usando previousElementSibling para obter o irmão anterior até que não haja mais nenhum. Esta propriedade retornará null quando atingimos o primeiro elemento da lista.

    1
    let lawyer = document.querySelector(".lawyer");
    
    2
    
    
    3
    let prev_siblings = [];
    
    4
    
    
    5
    let prev_elem = lawyer.previousElementSibling;
    
    6
    
    
    7
    while(prev_elem) {
    
    8
      prev_siblings.push(prev_elem); 
    
    9
      prev_elem = prev_elem.previousElementSibling;
    
    10
    }
    
    11
    
    
    12
    // Array(6) [ li, li, li, li, li, li ]
    
    
    13
    console.log(prev_siblings);
    
    14
    
    
    15
    /*
    
    
    16
    Emily
    
    
    17
    Emma
    
    
    18
    Amanda
    
    
    19
    John
    
    
    20
    Charles
    
    
    21
    Adam
    
    
    22
    */
    
    23
    for(sibling of prev_siblings) {
    
    24
      console.log(sibling.textContent);
    
    25
    }
    

    Encontre todos os próximos irmãos de um elemento

    Podemos proceder de maneira semelhante para encontrar todos os próximos irmãos de um elemento. A única mudança que precisamos fazer é o uso de nextElementSibling propriedade em vez de previousElementSibling propriedade. Aqui está um exemplo:

    1
    let lawyer = document.querySelector(".lawyer");
    
    2
    
    
    3
    let next_siblings = [];
    
    4
    
    
    5
    let next_elem = lawyer.nextElementSibling;
    
    6
    
    
    7
    while(next_elem) {
    
    8
      next_siblings.push(next_elem);
    
    9
      
    
    10
      next_elem = next_elem.nextElementSibling;
    
    11
    }
    
    12
    
    
    13
    // Array(4) [ li, li, li, li ]
    
    
    14
    console.log(next_siblings);
    
    15
    
    
    16
    /*
    
    
    17
    Hank
    
    
    18
    Walter
    
    
    19
    Skyler
    
    
    20
    Jesse
    
    
    21
    */
    
    22
    for(sibling of next_siblings) {
    
    23
      console.log(sibling.textContent);
    
    24
    }
    

    Pensamentos finais

    Percorrer o DOM para encontrar os pais, ancestrais, filhos, descendentes ou irmãos de um elemento agora é bastante fácil com JavaScript. Você pode simplesmente usar as propriedades parentElement, children, nextElementSibling e previousElementSibling para encontrar o pai, filhos, próximo irmão ou irmãos anteriores de qualquer elemento. Você também pode usar o closest() método se você estiver procurando por um antepassado específico ou pode usar o método querySelector() método se você estiver procurando por um descendente específico.

    Deixe uma resposta