Home » Jquery » javascript – Getting click event from parent container except certain children-Exceptionshub

javascript – Getting click event from parent container except certain children-Exceptionshub

Posted by: admin February 24, 2020 Leave a comment

Questions:

Expected behavior: When I click on the .parent class, an item detail modal will be shown but the modal won’t be shown if I click on the .dropdown or any of it’s option.

<div class="parent click-for-item-detail">

  <div class="dropdown">                                         
    <a href="#" class="dropdown-toggle " data-toggle="dropdown">Options</a>                                         
    <ul class="dropdown-menu">                                         
      <li><a href="#">option-1</a></li>
      <li><a href="#">option-2</a></li>                                         
    </ul>                                      
  </div>

  <div class="item-image"><img class="click-for-item-detail" src="image.jpg></div>

  <div class="info">
    <a href="#" class="click-for-item-detail">Item title</a>
    <div class="click-for-item-detail"> item subtitle</div>
  </div>

</div>

So far:

$(".click-for-item-detail").on("click",function(e){

        // show the modal if the target itself has been clicked
        if(e.target === this) {
            $('#itemDetailModal').modal('toggle');
        }
    });

I have added click-for-item-detail class in every element that should trigger the item detail modal. Is there a better way to achieve this?

How to&Answer:

It is true what Phong is saying and that works. However, imagine now you had many child elements in your parent all matching that selector. With something like below, you would add an event listener to each of those elements.

$(".info, .item-image").on("click", function(){
  console.log("Trigger");
});

While with your first approach you were already very close to only have one listener, no matter how many child elements are in the parent.

Consider following example:

  <ul class='parent'>
    <li>No</li>
    <li>Click</li>
    <li>Event</li>
  </ul>

$(".parent").on("click",function(e) {
  if(!e.target.classList.contains('parent')) {
     return console.log('no event')
} 
  console.log('fire event')
});

This is called event delegation, and you pretty much do this already. Here I am checking if the element, I am clicking on, is indeed of class parent, only then I fire my event.

You can of course do all sorts of checks, for example only the <li> elements.

$(".parent").on("click", (e) => e.target.tagName == 'LI' && console.log('fire event'))

Here check out this example https://codepen.io/bluebrown/pen/xxGVgYd?editors=1111

I would recommend doing a web search for event delegation and event bubbling.

Answer:

You can specify some selectors to be able to trigger.

Read the following post to have a better understanding.

Event listener for multiple elements – jQuery

$(".info, .item-image").on("click", function(){
  console.log("Trigger");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent click-for-item-detail">

  <div class="dropdown">                                         
    <a href="#" class="dropdown-toggle " data-toggle="dropdown">Options</a>                                         
    <ul class="dropdown-menu">                                         
      <li><a href="#" class="dropdown-menu-item">option-1</a></li>
      <li><a href="#" class="dropdown-menu-item">option-2</a></li>                                         
    </ul>                                      
  </div>

  <div class="item-image"><img class="click-for-item-detail" src="image.jpg"></div>

  <div class="info">
    <a href="#" class="click-for-item-detail">Item title</a>
    <div class="click-for-item-detail"> item subtitle</div>
  </div>

</div>

Answer:

You can use :not() selector to filter out the element you do not to be clicked:

$('.parent > :not(.dropdown)').click(function(e){
  alert('modal');
  //show modal
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">

  <div class="dropdown">                                         
    <a href="#" class="dropdown-toggle " data-toggle="dropdown">Options</a>                                         
    <ul class="dropdown-menu">                                         
      <li><a href="#">option-1</a></li>
      <li><a href="#">option-2</a></li>                                         
    </ul>                                      
  </div>

  <div class="item-image"><img src="image.jpg"></div>

  <div class="info">
    <a href="#">Item title</a>
    <div> item subtitle</div>
  </div>

</div>