Установка onclick для использования текущего значения переменной в цикле
Название может не иметь смысла и ни описания, а вот образец кода:
for(var a=0;a<10;a++) {
var b=document.createElement('b')
b.onclick=function() {
alert(a)
}
b.innerHTML=a
document.body.appendChild(b)
}
Что странно, когда я устанавливаю innerHTML в a, он использует текущее значение a. Таким образом, этот код создает десять <b>
элементов со значениями 0, 1, 2, 3, 4, 5, 6, 7, 8 и 9. Это работает отлично. Однако не является функцией onclick. Он возвращает окончательное значение a
(10) при нажатии любого из этих элементов. Я попытался установить другую переменную в a
, а затем использовать эту другую переменную в событии onclick, но все же возвращает окончательное значение a
. Как я могу использовать значение a
при установке onclick?
Ответы
Ответ 1
Попробуйте выполнить
b.onclick= function(arg) {
return function() {
alert(arg);
}
}(a);
Проблема, с которой вы столкнулись, заключается в том, что javascript не использует область блока. Вместо этого все переменные имеют время жизни их содержащей функции. Таким образом, во всех функциях onclick
был зафиксирован только один a
, и все они видят его окончательное значение.
Решение работает вокруг этого, создавая новую функцию и значение для каждой области, а затем сразу же устанавливая это значение на текущее значение a
.
Здесь версия, которая немного расширена и, возможно, более читаема
var createClickHandler = function(arg) {
return function() { alert(arg); };
}
for(var a=0;a<10;a++) {
var b=document.createElement('b')
b.onclick = createClickHandler(a);
b.innerHTML=a
document.body.appendChild(b)
}
Ответ 2
Один грязный обходной путь, который я обнаружил, заключается в использовании свойства .value
созданного объекта для хранения аргумента, который мы хотим передать функции .onclick
. Поэтому я могу сделать что-то вроде
for(var a=0;a<10;a++) {
var b=document.createElement('b')
b.value=a
b.onclick=function() {
myfunc(this.value)
}
b.innerHTML=a
document.body.appendChild(b)
}
function myfunc(n){
console.log(n)
}
Я не уверен, что .value работает с каждым элементом, но, например, для DIV.
EDIT: чтобы передать больше значений, то вы можете объединить их с помощью какого-либо символа, как _, а затем разделить его
b.value=x+"_"+y+"_"+z
function myfunc(str){
t=str.split("_")
x=t[0]
y=t[1]
z=t[2]
console.log(x+","+y+","+z)
}