在Javascript onClick事件中传递参数

fat*_*atz 48 javascript closures

我正在尝试在onclick事件中传递一个参数.以下是示例代码:

<div id="div"></div>

<script language="javascript" type="text/javascript">
   var div = document.getElementById('div');

   for (var i = 0; i < 10; i++) {
       var link = document.createElement('a');
       link.setAttribute('href', '#');
       link.innerHTML = i + '';
       link.onclick=  function() { onClickLink(i+'');};
       div.appendChild(link);
       div.appendChild(document.createElement('BR'));
       }

   function onClickLink(text) {
       alert('Link ' + text + ' clicked');
       return false;
       }
    </script>
Run Code Online (Sandbox Code Playgroud)

但是,每当我点击任何链接时,警报总会显示"Link 10 clicked"!

谁能告诉我我做错了什么?

谢谢

Jam*_*ong 53

发生这种情况是因为一旦调用函数,i就会向上传播范围.您可以使用闭包来避免此问题.

for (var i = 0; i < 10; i++) {
   var link = document.createElement('a');
   link.setAttribute('href', '#');
   link.innerHTML = i + '';
   link.onclick = (function() {
      var currentI = i;
      return function() { 
          onClickLink(currentI + '');
      }
   })();
   div.appendChild(link);
   div.appendChild(document.createElement('BR'));
}
Run Code Online (Sandbox Code Playgroud)

或者如果你想要更简洁的语法,我建议你使用Nick Craver的解决方案.


Nic*_*ver 37

发生这种情况是因为它们都引用了相同的 i变量,这个变量正在改变每个循环,并10在循环结束时保留.你可以使用这样的闭包来解决它:

link.onclick = function(j) { return function() { onClickLink(j+''); }; }(i);
Run Code Online (Sandbox Code Playgroud)

你可以在这里尝试一下

或者,make this成为您在该处理程序中单击的链接,如下所示:

link.onclick = function(j) { return function() { onClickLink.call(this, j); }; }(i);
Run Code Online (Sandbox Code Playgroud)

你可以在这里试试那个版本

  • @dierre - `(i)`调用`function(j)`,参数是当前的`i`,触发它返回一个复制值在闭包中的函数,不再连接到`i` , 合理? (3认同)