我在这个简单的闭包中做错了什么

发布于 2024-08-18 09:07:08 字数 769 浏览 7 评论 0原文

这可能是睡眠不足,但我不明白为什么这不起作用。我希望 onclick 从创建元素并应用事件处理程序的 for 循环返回 i 的值。已将其放入闭包中,但它仍在转动迭代器的最大数量。

window.onload = function(){
  var arbitrary_amount = 100;
  var the_list = document.getElementsByTagName('ul')[0];
  
  for(var i = 0; i < arbitrary_amount; i++){
    var natural_index = i + 1;
    var list_item = document.createElement('li');
    var inner_link = document.createElement('a');
    inner_link.setAttribute('href', '#');
    inner_link.innerHTML = "Link "+natural_index;
    
    inner_link.onclick = function(){
      return function(link_num){
        alert('You clicked link '+link_num);
      }(i);
    };
    
    list_item.appendChild(inner_link);
    the_list.appendChild(list_item);
  }
  
  
};

It maybe sleep deprivation but I cannot understand why this isn't working. I want the onclick to return the value of i from a for loop that created the element and applied the event handler. Have put it in a closure and it is still turning the max number of the iterator.

window.onload = function(){
  var arbitrary_amount = 100;
  var the_list = document.getElementsByTagName('ul')[0];
  
  for(var i = 0; i < arbitrary_amount; i++){
    var natural_index = i + 1;
    var list_item = document.createElement('li');
    var inner_link = document.createElement('a');
    inner_link.setAttribute('href', '#');
    inner_link.innerHTML = "Link "+natural_index;
    
    inner_link.onclick = function(){
      return function(link_num){
        alert('You clicked link '+link_num);
      }(i);
    };
    
    list_item.appendChild(inner_link);
    the_list.appendChild(list_item);
  }
  
  
};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

如日中天 2024-08-25 09:07:08

您以错误的方式使用闭包...我无法为您提供有关实际发生的情况的专家型答案,但这是一个有效的(未测试它)闭包:

inner_link.onclick = (function(link_num){
   return function(){
       alert('You clicked link '+link_num);
   };
})(i);

you are using the closure in the wrong way...i can't give you a guru type answer as to what was actually happening but here is a working (didn't test it) closure:

inner_link.onclick = (function(link_num){
   return function(){
       alert('You clicked link '+link_num);
   };
})(i);
用心笑 2024-08-25 09:07:08

您可以尝试:

window.onload = function(){
  var arbitrary_amount = 100;
  var the_list = document.getElementsByTagName('ul')[0];

  for(var i = 0; i < arbitrary_amount; i++){
    (function(){var natural_index = i + 1;
    var list_item = document.createElement('li');
    var inner_link = document.createElement('a');
    inner_link.setAttribute('href', '#');
    inner_link.innerHTML = "Link "+natural_index;

    inner_link.onclick = function(){
      return function(link_num){
        alert('You clicked link '+link_num);
      }(i);
    };

    list_item.appendChild(inner_link);
    the_list.appendChild(list_item);})();
  }


};

You can try with:

window.onload = function(){
  var arbitrary_amount = 100;
  var the_list = document.getElementsByTagName('ul')[0];

  for(var i = 0; i < arbitrary_amount; i++){
    (function(){var natural_index = i + 1;
    var list_item = document.createElement('li');
    var inner_link = document.createElement('a');
    inner_link.setAttribute('href', '#');
    inner_link.innerHTML = "Link "+natural_index;

    inner_link.onclick = function(){
      return function(link_num){
        alert('You clicked link '+link_num);
      }(i);
    };

    list_item.appendChild(inner_link);
    the_list.appendChild(list_item);})();
  }


};
╭⌒浅淡时光〆 2024-08-25 09:07:08

这是因为您为 onclick 处理程序创建的每个闭包共享相同的环境。当执行onclick回调函数时,每一个都引用i的最后一个值。

已经有各种解决方案,所以我不会在这里重复,但想法是创建不共享相同环境的额外闭包。

这是一个常见的错误。请查看这篇 MDC 文章,了解更多见解。

It's because each closure you create for the onclick handler shares the same environment. When the onclick callback function is executed, each one refers to the last value of i.

There are already various solutions out, so I won't repeat it here, but the idea is to create additional closures that do not share the same environment.

It's a common mistake. Checkout this MDC article for more insights.

风吹雪碎 2024-08-25 09:07:08

您的代码在 Firefox 3.5.5 和 Chrome 4.0.249.64 中可以正常工作。

Your code works correctly for me in Firefox 3.5.5 and Chrome 4.0.249.64.

栩栩如生 2024-08-25 09:07:08
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">


<head>


<title>Just testing</title>


<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />


</head>
<body>



<div id="test1">
Testing
</div>




<script type="text/javascript">


//  self-invoking function


(function makeHR(){
      var newHR = document.createElement('hr');
      document.getElementById('test1').appendChild(newHR);
})();





function makeLink(j){


      var link =document.createElement("a");


  link.innerHTML ="<br>Link test " +j;


  link.setAttribute('href', '#');

  link.onclick = (function(link_num){


   return function(){


   alert('You clicked link '+link_num);

   };


  })(j);

  document.body.appendChild(link);
}


for (var i=1; i<4; i++) {

   makeLink(i);

}


</script>


</body>

</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">


<head>


<title>Just testing</title>


<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />


</head>
<body>



<div id="test1">
Testing
</div>




<script type="text/javascript">


//  self-invoking function


(function makeHR(){
      var newHR = document.createElement('hr');
      document.getElementById('test1').appendChild(newHR);
})();





function makeLink(j){


      var link =document.createElement("a");


  link.innerHTML ="<br>Link test " +j;


  link.setAttribute('href', '#');

  link.onclick = (function(link_num){


   return function(){


   alert('You clicked link '+link_num);

   };


  })(j);

  document.body.appendChild(link);
}


for (var i=1; i<4; i++) {

   makeLink(i);

}


</script>


</body>

</html>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文