JavaScript 下拉菜单和外部 JavaScript 有问题

Problem with JavaScript dropdown & external JavaScript

将我的 js 代码放入外部 js 文件时,我的 JavaScript 下拉菜单无法正常工作。需要按两次按钮才能显示链接。如果我使用脚本标签将 js 代码放在 body 部分,我可以毫无问题地使代码工作。

我一直在努力理解其中的区别,但还没有想出解决办法。起初我认为在 js 文件中使用它就足够了,然后像下面那样在 html 文件中使用 onlick="dropdownfunc()",但似乎我错了。

我需要考虑什么才能让它发挥作用?

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>

这与js是否是外部无关。

事情是这样的:

第一次点击时,dropdownfunc 被调用。它为点击附加了另一个事件侦听器,并且什么都不做,所以在 UI.

上什么也没有发生

第二次点击时,将调用第二个侦听器并显示下拉列表。对了,dropdownfunc也会被再次调用!

实际上,每次单击按钮时,dropdownfunc 都会添加相同的侦听器。所以你在堆积听众。你应该避免这种情况!

这是因为您在单击后再次附加单击事件处理程序,您已经在 onclick="dropdownfunc()" 中定义了该处理程序。相反,您可以简单地将 this 作为参数添加到 onclick 函数并显示下拉列表。无需循环浏览您的按钮。这是一个例子:

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>