Search code examples
jqueryparentchildren

child and parent fire two different events when clicked on a child


I have this html structure:

<div class="dropdownedit">
<div class="dropbtn">textxyz</div>
<div class="dropdown-content" style="display: none;">
<div href="#" class="ocond" id="text1">text1</div>
<div href="#" class="ocond" id="text2">text2</div>
<div href="#" class="ocond" id="text3">text3</div>
<div href="#" class="ocond" id="text4">text4</div>
</div></div>

and this jquery events to handle the dropdown view/hide events:

 $(document).on('click',".dropdownedit", function (e) {
$(this).children('.dropdown-content').css("display", "block");
     });

   $(document).on('mouseover',".dropdown-content", function (e) {
$(this).css("display", "block");
     });

   $(document).on('mouseout',".dropdown-content", function (e) {
$(this).css("display", "none");
   });

Furthermore I have a on-click-event for the class "ocond" that should close the dropdown-content class when a option is clicked in the dropdown menu:

$(this).parents('.dropdown-content').css("display", "none"); 

but it is not closing after the click it stays visible. I guess it conflicts with:

$(document).on('click',".dropdownedit", function (e) {
$(this).children('.dropdown-content').css("display", "block");
     });

due to the fact that dropdownedit is a parent of the "ocond"-class div and is fired as well when someone clicks on the "ocond" class.

I try to add to prevent the parent event when clicked on the child event:

$(".dropdownedit .ocond").click(function(e) {
    e.stopPropagation();

});

but no success. How could I solve this conflict?


Solution

  • You're right, the commands are conflicting with each other. If you come down one level for the click event which is designed to leave the menu open and add a class to override the hover show/hide functionality then you will get the results you want without a conflict.

    Attaching the .click() event to the .dropbtn and using .nextAll() to find the .dropdown-content will avoid the current conflict.

    N.B. I've used .nextAll() which finds all the siblings that match a particular selector, I've followed this with .first() so that the code only affects the first instance of this. It means it is less likely to interfere with other code.

    I would also strongly advise using .closest() (which will find the first occurrence of a selector immediately upstream) rather than .parents() that will match any.

    $(".dropbtn").click( function() { 
      $(this).nextAll(".dropdown-content").first().show();
    });
    
    $(".dropdownedit").mouseleave( function() { 
      $(this).find(".dropdown-content").hide();
    });
    
    $(".ocond").click( function() { 
      $(this).closest('.dropdown-content').hide(); 
    });
    .dropdown-content {
      display: none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
    <div class="dropdownedit">
      <div class="dropbtn">textxyz</div>
      <div class="dropdown-content">
        <div href="#" class="ocond" id="text1">text1</div>
        <div href="#" class="ocond" id="text2">text2</div>
        <div href="#" class="ocond" id="text3">text3</div>
        <div href="#" class="ocond" id="text4">text4</div>
      </div>
    </div>