-4

I'm trying to create a simple custom dropdown with absolute position in its container parent, and when the parent is clicked it has to show the dropdown. the problem is that when I click on the child its calling the click method of its parent.

click on the green area (the parent).

function clickHere() {

  if (document.getElementById("drop").style.display == "block") {
    document.getElementById("drop").style.display = "none";
  } else {
    document.getElementById("drop").style.display = "block";
  }
}
<div style="background:red; height:500px;">
  <div onclick="clickHere()" style="margin:auto;height: 40px; width:30%; background:green; position:relative;">
    <div id="drop" style="display:none;width:100%; height:200px; background:blue; position:absolute; top: 100%; margin:0;">
      <h3 style="text-align: center; color:white;">Hello</h3>
      <h3 style="text-align: center; color:white;">Hello</h3>
      <h3 style="text-align: center; color:white;">Hello</h3>
      <h3 style="text-align: center; color:white;">Hello</h3>
    </div>
  </div>
</div>

2 Answers2

0

You can pass the click event to the callback function. Then you can check for the event.target element and react to it, returning false to do nothing or proceeding with your code.

For the sake of this demonstration, I simply check if there is a click handler set on the element, but as you will probably have click handlers on the child elements later as well, you might want to check for event.target.tagName, event.target.id a specific class name, or any other distinctive feature.

As suggested in the comments, another possibility is to register a listener on the child elements and then call event.stopPropagation(), but using this approach, one listener is sufficient.

function clickHere(event) {
  var target = event.target;
  if (!event.target.onclick) return false;
  
  if (document.getElementById("drop").style.display == "block") {
    document.getElementById("drop").style.display = "none";
  } else {
    document.getElementById("drop").style.display = "block";
  }
}
<div style="background:red; height:500px;">
  <div onclick="clickHere(event)" style="margin:auto;height: 40px; width:30%; background:green; position:relative;">
    <div id="drop" style="display:none;width:100%; height:200px; background:blue; position:absolute; top: 100%; margin:0;">
      <h3 style="text-align: center; color:white;">Hello</h3>
      <h3 style="text-align: center; color:white;">Hello</h3>
      <h3 style="text-align: center; color:white;">Hello</h3>
      <h3 style="text-align: center; color:white;">Hello</h3>
    </div>
  </div>
</div>
Constantin Groß
  • 10,719
  • 4
  • 24
  • 50
0

change call to the handler to clickhere(event)

change the clickhere function to clickere(e) and add a call to e.stopPropagation() to the function.

Events bubble up the hierarchy by default.

Grant H
  • 1
  • 1