2013-03-09 4 views
0

этот код беспокоил меня целый день. Предположим, что ledCount = 9, код получает элементы по идентификатору без каких-либо проблем, но поскольку ему придется привязывать отдельную функцию onClick, а так как переменная i является локальной, функция writeLED всегда получает первый параметр 10 (который максимальный i + 1), но ему нужно будет получить текущий i + 1, как это делает getElementBy id i + 1. Любой может решить загадку?Javascript - использовать переменную в функции, в функции

function showLED(ledCount){ 
for(var i = 0;i<=(ledCount-1);i++){ 
    if(color[i] == 0){ 
     document.getElementById('buttonLED'+(i+1)).onclick = function(){writeLED((i+1),1); } ; 
     document.getElementById('buttonLED'+(i+1)).value="light is on"; 
    }else{ 
     document.getElementById('buttonLED'+(i+1)).onclick = function(){writeLED((i+1),0); } ; 
     document.getElementById('buttonLED'+(i+1)).value="light is off"; 
    } 
} 
} 

ответ

3

Вам нужно обернуть его в прямоприменяемой функции создать новую область, где вы можете сохранить текущее значение функции Инкрементирования.

Вы можете сделать это инлайн так:

document.getElementById('buttonLED'+(i+1)).onclick = function(loopincrement){ 
    return function(){writeLED((loopincrement+1),1); } ; 

}(i) 

или как вытащил из функции, как это:

function writeLEDInNewScope(inc){ 
    return function(){ writeLED(inc,1)}; 
} 

document.getElementById('buttonLED'+(i+1)).onclick = writeLEDinNewScope(i+1); 

Внешняя функция сохранит текущее значение значение, которое я для внутренней OnClick функции , Он выполняется немедленно и возвращает внутреннюю функцию, которую вы хотите связать с свойством onclick. Он будет поддерживать ссылку на переменную loopincrement, которая не будет выполняться итерациями будущего цикла.

+0

Несмотря на то, что это правильно, тем более современный способ сделать это с 'func.apply()' - так или иначе, OP должен прочитать о замыканиях. –

+0

Вы можете просто затенять 'i', передав его как аргумент внешней функции. – Blender

+0

@David - Я, хотя это применит, фактически выполнит функцию с явным 'this' и массивом аргументов, уверены ли вы, что O.K назначает ей обратный вызов? – 2013-03-09 21:45:25

1

Это infamous for loop problem. Вы должны переписать код так:

function callback(x) { 
    return function() { writeLED(x, 1); }; 
} 

function showLED(ledCount) { 
    for (var i = 0; i <= (ledCount - 1); i++)(function(i) { 
     if (color[i] == 0) { 
      document.getElementById('buttonLED' + (i + 1)).onclick = callback(i + 1); 
      document.getElementById('buttonLED' + (i + 1)).value = "light is on"; 
     } else { 
      document.getElementById('buttonLED' + (i + 1)).onclick = callback(i + 1); 
      document.getElementById('buttonLED' + (i + 1)).value = "light is off"; 
     } 
    })(i); 
} 
Смежные вопросы