Find an ancestor with a certain class from any descending element with pure Javascript

Asked

Viewed 106 times

2

With jQuery it is quite simple to find an ancestral element that has a certain class, id, attribute etc. using the method .closest(). For example, in the code below I can select the div#principal by clicking on any of their descendants:

$("#principal *").on("click", function(evt){

   var elemento_clicado = $(evt.target)[0];
   var ancestral = $(evt.target).closest("#principal")[0];
   console.log(elemento_clicado, ancestral);

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="principal">
  <div>Texto</div>
  <h3>titulo</h3>
  <strong>negrito</strong>
  <div>
    <p>sub-elemento</p>
    <div>
      <ul>
        <li>Lista 1</li>
      </ul>
    </div>
  </div>
</div>

No matter the level within #principal where the element is located, the .closest(seletor) will fetch the entered element from the selector (in case the div#principal).

I don’t know a Javascript method that does this function. I thought to use .parentNode but since the elements nested within the main div may have 1, 2, 3 or multiple levels in the tree, I wouldn’t know how many .parentNode use when clicking on an element in level 1 or level 5, for example.

I arrived at this code that returns to me the element clicked:

var itens = document.querySelectorAll("#principal .item");
for(var x=0; x < itens.length; x++){
   
   itens[x].onclick = function(evt){
      console.log(evt.target);
   }
   
}
.item{
   background: orange;
   margin-bottom: 1px;
}

.item *{
   background: red;
}
<div id="principal">
   <div class="item">
      <p>
         <strong>Texto 1</strong>
      </p>
   </div>
   <div class="item">
      <h3>Título</h3>
      <p>
         <strong>Texto 2</strong>
      </p>
   </div>
   <div class="item">
      <h3>Título</h3>
      <p>
         <strong>Texto 3</strong>
      </p>
      <div class="item2">
         <div>
            <p>
               Texto 4 <strong>mais...</strong>
            </p>
         </div>
      </div>
   </div>
</div>

In the hypothetical example above, how would I get to the div with the class .item by clicking on any of their descendants, such as .closest(".item") jQuery?

1 answer

2


At this time pure JS also has a closest same as Jquery. It also takes a selector and is a Element, which in this case will be an element obtained from the FOD. See in the documentation.

Your code would suffice then:

evt.target.closest(".item")

Example:

var itens = document.querySelectorAll("#principal .item");
for(var x=0; x < itens.length; x++){
   
   itens[x].onclick = function(evt){
      var elemento_clicado = evt.target;
      var ancestral = evt.target.closest(".item");
      console.log(elemento_clicado, ancestral);
   }
   
}
.item{
   background: orange;
   margin-bottom: 1px;
}

.item *{
   background: red;
}
<div id="principal">
   <div class="item">
      <p>
         <strong>Texto 1</strong>
      </p>
   </div>
   <div class="item">
      <h3>Título</h3>
      <p>
         <strong>Texto 2</strong>
      </p>
   </div>
   <div class="item">
      <h3>Título</h3>
      <p>
         <strong>Texto 3</strong>
      </p>
      <div class="item2">
         <div>
            <p>
               Texto 4 <strong>mais...</strong>
            </p>
         </div>
      </div>
   </div>
</div>

As you would expect there is no support for the mythical IE, however there is a polyfill on the documentation page if you need to.

  • Cool! I didn’t know this method. Obg!

  • 1

    @Sam Yeah, pure JS has been running after Jquery, creating more and more replicates than Jquery ever had, hehe

  • Yeah. Very good that. At first I was reluctant to use jQuery because I thought it was complicated (I was a beginner at the time) and I died to do things in JS. After I started wearing it I got addicted to practicality, but now I want to divorce him.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.