您如何正确编写JavaScript“ for”循环?

时间:2019-02-18 03:19:27

标签: javascript html css loops

我链接的GitHub存储库将不会用于其他任何问题(除非为帮助解决此问题,否则不会更改。...仅用于此问题

注意:我已经完成了研究,我相信我的代码应该可以工作

好吧,如果您需要我的其余代码对此做一个很好的判断,请随时访问:My Github Repository,仅用于这1个问题。在GitHub Repository中,还有一个CSS文件,但是没有问题,只需将其包含进去,这样您就可以看到所有代码。

是的,我知道当人们包含“ GitHub”链接时,该网站上的许多人都不喜欢它。但是,如果我没有把所有的代码都弄得一团糟,那对我来说就更容易解释了(如果我能缩小什么代码给我带来了错误,就更容易了

好,所以这个“ for”循环:

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

  for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
    dropdown[i].addEventListener("click", something());
    alert("Please work");
  }

实际上没有运行。当我在for循环上方放置“警报”时:

var dropdown = document.getElementsByClassName("dropdown-btn");


 var i;
 alert("This works");
  for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
    dropdown[i].addEventListener("click", something());
    alert("This does not work");
  }

在调用“ for”循环的方法后,将立即调用警报。我想解释一下我的问题,我的“ for”循环有什么问题吗? (这可以在其他.html文件中使用,所以我不确定为什么它不能在我的当前工作空间中工作。)

更新(2019年2月18日): 好的,所以我找到了导致错误的原因。

对于那些评论并建议我使用“ console.log(dropdown.length);”的人,这带来了意外的错误:

function something(){


this.classList.toggle("active");
  var dropdownContent = this.nextElementSibling;
  if (dropdownContent.style.display === "block") {
  dropdownContent.style.display = "none";
  } else {
  dropdownContent.style.display = "block";
  }
}

正如我最初说的那样,该工作在另一个文件中有效,但是由于某种原因,它说在“ this.classList.toggle(” active);“”中,“ toggle”未定义。这个应该要在此文件中定义,还是我认为是默认的“函数”?通过我的所有研究以及我对JavaScript语言的所有了解,我有信心这是默认的“功能”,除非有人能证明我错了,否则我不明白为什么它不起作用。

4 个答案:

答案 0 :(得分:3)

问题在于您将函数作为参数传递而没有将其包装在调用函数中。

有两种方法可以使这项工作。

  1. ()函数中删除something,并在something内部调用警报
    for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
      dropdown[i].addEventListener("click", something)
    }

    something () {
      alert('this is working')
      ...
    }
  1. 在事件处理程序中放置一个函数调用,并将两个函数调用都放在其中
    for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
      dropdown[i].addEventListener("click", function () {
        something();
        alert("This works");
      })
    }

Here是一个示例:

答案 1 :(得分:2)

您在调用something而不是在尝试添加eventListener时仅传递可调用函数。删除括号。

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

  for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
    dropdown[i].addEventListener("click", something);
  }
  
  function something() {
    this.classList.toggle("active");
    var dropdownContent = this.nextElementSibling;
    if (dropdownContent.style.display === "block") {
    dropdownContent.style.display = "none";
    } else {
    dropdownContent.style.display = "block";
    }
  }
<a class="dropdown-btn" href="#">Button 1</a>
<div style="display:none;">Dropdown Content Here</div>
<br />
<a class="dropdown-btn" href="#">Button 2</a>
<div style="display:none;">Dropdown Content Here</div>

答案 2 :(得分:1)

我在GitHub上查看存储库,发现html部分存在很多错误,因此JS部分无法工作。

仅此循环,当前的html部分是:

<button class="dropdown-btn" onclick="drop()">OUR STORY 
  <i class="fa-caret-down"></i>
</button>

因此,第一次drop()函数会在按钮上创建一个新的事件侦听器,但不会调用它。 如果第二次单击该按钮,则将启动2个操作:第一个操作再次添加新的事件侦听器,然后单击该按钮, 第二个是第一次创建事件监听器的触发。

有2种可能的解决方案

解决方案1 ​​

<button class="dropdown-btn" onclick="something()">OUR STORY 
  <i class="fa-caret-down"></i>
</button>    

解决方案2

<button class="dropdown-btn" >OUR STORY 
  <i class="fa-caret-down"></i>
</button>

在JS =(!中删除函数drop()声明!)

var dropdown = document.getElementsByClassName("dropdown-btn");

for (let i = 0, iMax=dropdown.length ; i < iMax ; i++) {
  dropdown[i].addEventListener("click", something);
}

为帮助您理解代码错误的原因,请尝试以下示例代码

var Compteur = 0;


function something(){
  console.log('call on something()', ++Compteur);
}


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

  for (let i = 0; i < dropdown.length; i++) { 
    dropdown[i].addEventListener("click", something);
    console.log( 'adding event Listener on one dropdown-btn ', ++Compteur);
  }
}
<button class="dropdown-btn" onclick="drop()">OUR STORY </button>

答案 3 :(得分:1)

这是您的问题。

问自己为什么会得到this.classList的未定义内容?

如果进一步看,您会发现this是没有classList的窗口对象。现在问自己为什么是窗户对象?

这是因为something()是事件侦听器,应响应事件来调用它。在dropdown[i].addEventListener("click", something());行中,您没有将something()分配为事件处理程序,而是在没有事件的情况下调用该方法,因此没有this.classList,因为this是窗口对象。

正如other answers所述,您需要将其更改为:

dropdown[i].addEventListener("click", something);

something()事件分配给click事件,而不调用它。

完整示例

function something(){
  console.log(this); //For Debug prurposes
  this.classList.toggle("active");
  var dropdownContent = this.nextElementSibling;
  if (dropdownContent.style.display === "block") {
  dropdownContent.style.display = "none";
  } else {
  dropdownContent.style.display = "block";
  }
}


/* Loop through all dropdown buttons to toggle between hiding and showing its dropdown content - This allows the user to have multiple dropdowns without any conflict */
function drop(){
  var dropdown = document.getElementsByClassName("dropdown-btn");
  var i;

  for (i = 0; i < dropdown.length; i++) { //this is not getting called for some reason
    dropdown[i].addEventListener("click", something);
    console.log("Please wokrk");
  }
}
.sidenav a, .dropdown-btn {
  padding: 6px 8px 6px 16px;
  text-decoration: none;
  font-size: 20px;
  color: #818181;
  display: block;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
  outline: none;
}

.active {
  background-color: green;
  color: white;
}

.dropdown-container {
  display: none;
  background-color: #262626;
  padding-left: 8px;
}
<button class="dropdown-btn" onclick="drop()">OUR STORY 
    <i class="fa-caret-down"></i>
  </button>
  <div class="dropdown-container">
    <a href="#about_us">ABOUT US</a>
    <a href="#community">COMMUNITY</a>
    <a href="#">HUMANITARIAN ACTION</a>
  </div>

另一方面,使用onClick=drop()之类的内联事件然后将其他事件侦听器绑定到同一元素是很不常见的。实际上,最好的方法是避免一起使用内联JavaScript。

以后,请在问题本身中包含与该问题相关的所有代码。正如我在评论中提到的,它使我们更容易帮助您