2016-09-29 311 views
0

首先,我找到了一些似乎解决这个问题的链接,但是我对javascript(以及一般的代码)的理解非常糟糕,解决方案/解释对我来说很难概括这里。我知道这与封闭有关(我隐约明白)。用for循环创建多个函数

背景: 我创建使用循环中,每个与应该当复选框被选中出现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的循环不只是吐在10层不同的功能我的PHP循环吐出10个不同的复选框的方式?

谢谢!

+0

你不需要多个函数..从来没有在循环.. – Rayon

+1

可能重复[JavaScript闭合内部循环 - 简单实用的例子](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops -simple-practical-example) – vlaz

+0

除了重复之外,我甚至不知道为什么要使用10个函数,而不是简单地使用1个参数。 – vlaz

回答

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 ?> 
+0

这太聪明了!我不知道我为什么没有这样想,因为它更符合我的编码能力......谢谢! – danny

+0

@danny - 谢谢你的补充..我欣赏那.. – Rayon

1

您的问题是var悬挂,所以你得到10个不同的功能,每个人指着一个共享变量...指向在最后一组复选框。

第一解决问题的方法是使用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 
} 
+0

谢谢,这太棒了!第二个代码框远远超出了我,但它看起来比我一直在做的更优雅。不过,我想我会坚持人造丝的解决方案。 – danny

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); 
} 
0

肖恩有问题,但那里是做比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

该作品通过将变量存储在只能由返回函数访问的第一个函数中的范围内。

人造丝拥有比循环功能更好的解决方案,但是可以处理任何行的函数意味着它会扩展或缩小到您的需求。