Присвоить события внутри цикла
Уважаемые знатоки, прошу помочь. Как присвоить соответствующей кнопке событие, которое выведет значение из соответствующего поля ввода в консоль?
Вот что имею: for(i=0;i<3;i++){ inp = document.createElement('input') btn = document.createElement('input') inp.className='inpt' btn.className='but' btn.type='button' btn.value = 'click' document.body.appendChild(inp) document.body.appendChild(btn) document.getElementsByClassName('but')[i].onclick = function(){ console.log(document.getElementsByClassName('inpt')[i].value) } } |
document.getElementsByClassName('inpt')[i].value // -> this.value |
Koyf,
Выше правильный вариант подсказали, но вообще ваша проблема в том, что при создании всех коллбеков на onclick они замкнуты на одно и то же окружение(в данном случае -- глобальный объект), соответственно i в них всех вычисляется в последнее значение, вернувшееся из цикла. вот наглядный пример: arrayOfFunctions = [] i = 10 while(i--) arrayOfFunctions.push(function(){console.log(i)}) i = "foo" arrayOfFunctions.forEach(function(f){f()}) //>>>> foo //>>>> foo //>>>> foo //>>>> foo //>>>> foo //>>>> foo //>>>> foo //>>>> foo //>>>> foo //>>>> foo Не всегда очевидное для новичков поведение. Просто имейте это в виду. UPD а добится желаемого эффекта довольно легко: просто компилировать ф-ции на лету: arr = ["a", "b", "c"] functions = [] i = -1 while(i < 2){ ++i; functions.push(Function("f", "console.log(arr[" + i + "])")) } i = -1 while(i < 2){ ++i; functions.push(function(f){console.log(arr[i])}) } functions.forEach(function(f){f()}) //>>>> a //>>>> b //>>>> c //>>>> c //>>>> c //>>>> c можно еще создавать дополнительные замыкания на каждой итерации или в ES6 можете еще воспользоваться декларацией переменных с блочной видимостью, но злоупотреблять этим не следует, так как это серьезный жер памяти. |
Всем спасибо за помощь, наконец таки разобрался)
Вдруг кому пригодится for(i=0;i<3;i++){ inp = document.createElement('input') btn = document.createElement('input') inp.className='inpt' btn.className='but' btn.type='button' btn.value = 'click' document.body.appendChild(inp) document.body.appendChild(btn) document.getElementsByClassName('but')[i].onclick = Function('f'+i,'console.log(document.getElementsByClassName("inpt")['+i+'].value)') } |
Koyf, нет не в этом.
Создание функций из текста - ужасное решение. |
Aetae,
Что в нем плохого? Я, кстати, не спорю, что для данного кейза Ваше решение лучше, о чем упомянул, но в общем случае, им не обойдешься. А из всех вариантов, которые тут возможны, которые сводятся, по сути, к 3-м случаям: создание отдельной структуры указателей(слишком сложно для этого), создание отдельных окружений для каждого коллбека, явно или или подковерно(с блочным сахаром типа let), что ведет к оверхеду по памяти и тормозам при массовом применении и компиляция на ходу, последнее явно предпочтительней |
Часовой пояс GMT +3, время: 17:19. |