Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 05.11.2016, 20:19
Новичок на форуме
Отправить личное сообщение для Koyf Посмотреть профиль Найти все сообщения от Koyf
 
Регистрация: 05.11.2016
Сообщений: 2

Присвоить события внутри цикла
Уважаемые знатоки, прошу помочь. Как присвоить соответствующей кнопке событие, которое выведет значение из соответствующего поля ввода в консоль?
Вот что имею:
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)
  }
}
Ответить с цитированием
  #2 (permalink)  
Старый 05.11.2016, 20:40
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,587

document.getElementsByClassName('inpt')[i].value
// ->
this.value
__________________
29375, 35
Ответить с цитированием
  #3 (permalink)  
Старый 05.11.2016, 21:05
Аспирант
Отправить личное сообщение для fuckingquest Посмотреть профиль Найти все сообщения от fuckingquest
 
Регистрация: 28.10.2016
Сообщений: 70

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 можете еще воспользоваться декларацией переменных с блочной видимостью, но злоупотреблять этим не следует, так как это серьезный жер памяти.

Последний раз редактировалось fuckingquest, 05.11.2016 в 21:29.
Ответить с цитированием
  #4 (permalink)  
Старый 05.11.2016, 22:33
Новичок на форуме
Отправить личное сообщение для Koyf Посмотреть профиль Найти все сообщения от Koyf
 
Регистрация: 05.11.2016
Сообщений: 2

Всем спасибо за помощь, наконец таки разобрался)
Вдруг кому пригодится
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, 06.11.2016 в 02:24.
Ответить с цитированием
  #5 (permalink)  
Старый 05.11.2016, 22:55
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,587

Koyf, нет не в этом.
Создание функций из текста - ужасное решение.
__________________
29375, 35
Ответить с цитированием
  #6 (permalink)  
Старый 06.11.2016, 00:43
Аспирант
Отправить личное сообщение для fuckingquest Посмотреть профиль Найти все сообщения от fuckingquest
 
Регистрация: 28.10.2016
Сообщений: 70

Aetae,
Что в нем плохого?
Я, кстати, не спорю, что для данного кейза Ваше решение лучше, о чем упомянул, но в общем случае, им не обойдешься. А из всех вариантов, которые тут возможны, которые сводятся, по сути, к 3-м случаям: создание отдельной структуры указателей(слишком сложно для этого), создание отдельных окружений для каждого коллбека, явно или или подковерно(с блочным сахаром типа let), что ведет к оверхеду по памяти и тормозам при массовом применении и компиляция на ходу, последнее явно предпочтительней
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Обработка события внутри события grifangel Общие вопросы Javascript 6 04.09.2014 12:34
Получение значения переменной внутри обработчика события jQuery Mbenga Общие вопросы Javascript 2 01.07.2013 10:57
Присвоить ссылке 2 события Vempel jQuery 2 24.07.2012 15:14
Как установить задержку внутри цикла for - ? caca0 Javascript под браузер 2 29.05.2012 15:12
Обработка события элемента внутри создавшего его объекта pauluss Общие вопросы Javascript 10 10.09.2010 17:01