Search code examples
javascriptdropdownexternal-js

Problem with JavaScript dropdown & external JavaScript


I have a problem to make my JavaScript dropdown work when placing my js code in an external js file. The button needs to be pressed twice to show the links. I have no problem to make the code work if i place the js code in the body section using script tags.

I have been trying to understand the difference, but not yet come up with a solution. At first I thought it would be enough to make a function of it in the js file and then use onlick="dropdownfunc()" in the html file like bellow, but seems like I am wrong.

What do I need to think about to make it work?

function dropdownfunc() {
  var dropdown = document.getElementsByClassName("dropdown-btn");
  var i;

  for (i = 0; i < dropdown.length; i++) {
    dropdown[i].addEventListener("click", function () {
      this.classList.toggle("active");
      var dropdownContent = this.nextElementSibling;
      if (dropdownContent.style.display === "block") {
        dropdownContent.style.display = "none";
      } else {
        dropdownContent.style.display = "block";
      }
    });
  }
}
.dropdown-btn {
  color: gray;
  font-size: 1.8rem;
  cursor: pointer;
}

.dropdown-container {
  display: none;
  border-left: 2px solid #818181;
}

.dropdown-links {
  display: table;
  font-size: 1.4rem;
  margin-left: 18px;
}

.active {
  color: black;
}
<button class="dropdown-btn" onclick="dropdownfunc()">Dropdown</button>

<div class="dropdown-container">
  <a class="dropdown-links" href="#">Link 1</a>
  <a class="dropdown-links" href="#">Link 2</a>
</div>


Solution

  • This is becasue you are attaching the click event handler again after the click, which you already defined in onclick="dropdownfunc()". Instead, you can simply add this as a parameter to your onclick function and display the dropdown. And no need to loop thru your buttons. Here is an example:

    function dropdownfunc(el) {
      el.classList.toggle("active");
      var dropdownContent = el.nextElementSibling;
      if (dropdownContent.style.display === "block") {
        dropdownContent.style.display = "none";
      } else {
        dropdownContent.style.display = "block";
      }
    }
    .dropdown-btn {
      color: gray;
      font-size: 1.8rem;
      cursor: pointer;
    }
    
    .dropdown-container {
      display: none;
      border-left: 2px solid #818181;
    }
    
    .dropdown-links {
      display: table;
      font-size: 1.4rem;
      margin-left: 18px;
    }
    
    .active {
      color: black;
    }
    <button class="dropdown-btn" onclick="dropdownfunc(this)">Dropdown</button>
    
    <div class="dropdown-container">
      <a class="dropdown-links" href="#">Link 1</a>
      <a class="dropdown-links" href="#">Link 2</a>
    </div>