使用for循环创建多个函数

时间:2016-09-29 16:18:12

标签: javascript function for-loop

首先,我确实找到了一些似乎可以解决这个问题的链接,但我对javascript(以及一般代码)的理解非常糟糕,而且解释/解释很难在这里概括。我知道它与闭包有关(我模糊地理解)。

背景 我使用一个循环创建了10个复选框,每个循环都有4个单选按钮,当选中复选框时应该会出现这些按钮。我可以通过逐个创建10个以上的函数来完成“出现/消失”,但我更喜欢用循环创建我的10个函数。下面的代码显示了每个复选框在更改时如何调用变量函数(例如,t0Disp())。

<?
for ($row = 0; $row <10; $row++)
{
  $topic = $topic[$row];
  ?>
  <input id="C<? echo $row ?>" type="checkbox" value="true" onchange="t<? echo $row ?>Disp()" /><? echo $topic ?>
  <br />
  <div id="<? echo $row ?>div" style="display: none">
      <? for ($col = 0; $col < 4; $col++) 
    {
      ?>
      <input type="radio" name="r<? echo $row ?>" value="<? echo $col ?>" onchange="disable<? echo $col ?>(); disable<? echo $row ?>();" />
      <? echo $col+1; ?>
    <?
    }
    ?>
      <br />
      <br />
  </div>
<?
}
?>

如果我通过t9Disp()函数手动输入我的t0Disp(),上面的代码工作正常。当我尝试使用for循环来创建这些函数时(下面),该函数仅适用于t9Disp()

for (var i=0; i<10; i++) {
    var idiv = i + "div";
    var eldiv = document.getElementById(idiv);
    var ci = "C" + i;
    var elci = document.getElementById(ci);
    window['t' + i + 'Disp'] = function() {
        if(elci.checked == true) {
            eldiv.style.display = "inherit";
        }
        else {
            eldiv.style.display = "none";
        }
    }
}

我只需要理解为什么javascript循环不只是以我的php循环吐出10个不同的复选框的方式吐出10个不同的函数?

谢谢!

4 个答案:

答案 0 :(得分:1)

您的问题是var已被提升,因此您获得十个不同的功能,每个功能指向一个共享变量...其中指向最后一组复选框。

问题的第一个解决方案是使用letconst(如果您只需要支持现代浏览器):

for (var i=0; i<10; i++) {
    const idiv = i + "div";
    const eldiv = document.getElementById(idiv);
    const ci = "C" + i;
    const elci = document.getElementById(ci);
    window['t' + i + 'Disp'] = function() {
        if(elci.checked == true) {
            eldiv.style.display = "inherit";
        }
        else {
            eldiv.style.display = "none";
        }
    }
}

然而,你可以做的更多:

const checkboxes = document.querySelectorAll('.js-showChoices');
[].slice.apply(checkboxes).forEach(checkbox => {
  checkbox.addEventListener('change', event => {
    if (event.target.checked) getDivFor(event.target).style.display = 'inherit';
    else getDivFor(event.target).style.display = 'none';
  });
});

function getDivFor(checkbox) {
  // Find div based on checkbox and return it
}

答案 1 :(得分:0)

你不需要多个函数,只有一个带参数的函数可以为你做到这一点!

function disp(elci, eldiv) {
  eldiv = document.getElementById('eldiv');
  if (elci.checked == true) {
    eldiv.style.display = "inherit";
  } else {
    eldiv.style.display = "none";
  }
}

你的标记将是:

<input id="C<? echo $row ?>" type="checkbox" value="true" onchange="Disp(this,'<? echo $row ?>div')" /><? echo $topic ?>

答案 2 :(得分:0)

代码的问题在于,当添加函数时,会记住变量eldielci的最后一个值。

您可以使用闭包来记住适当的变量值。 为此,做这样的事情

function addFunction(name, elementDiv, elementCi) {
  window[name] = function() {
    if(elementCi.checked == true) {
        elementDiv.style.display = "inherit";
    }
    else {
        elementDiv.style.display = "none";
    }
 }

}

for (var i=0; i<10; i++) {
   var idiv = i + "div";
   var eldiv = document.getElementById(idiv);
   var ci = "C" + i;
   var elci = document.getElementById(ci);
   addFunction('t' + i + 'Disp', eldiv, elci);
}

答案 3 :(得分:0)

Sean有问题,虽然有一个比consts更简单的方法,并支持以前的浏览器

for (var i=0; i<10; i++) {
    window['t' + i + 'Disp'] = (function() {
        var idiv = i + "div";
        var eldiv = document.getElementById(idiv);
        var ci = "C" + i;
        var elci = document.getElementById(ci);

        return function() {
            if(elci.checked == true) {
                eldiv.style.display = "inherit";
            } else {
                eldiv.style.display = "none";
            }
        };
    })();
}

JsFiddle

这可以通过将变量存储在第一个函数的范围内,该函数只能由返回的函数访问。

Rayon有一个比循环函数更好的解决方案,但是一个可以处理给它的任何行的函数意味着它可以根据你的需要扩展或收缩。