Добрый день,
В Javascript все переменные статические и определены в scope функции, это я знаю. Также знаю, что для захвата локальной переменной (в том ее состоянии, что есть сейчас) можно определить новую функцию, в ней скопировать переменную, тем самым создав новую переменную в другом scope. Тем не менее, пока не получается найти изящного решения практической проблемы.
Итак, в некой JS функции я прохожусь по циклу и динамически создаю элементы, по одному на итерацию. Например:
for (i = 0; i < 10; ++i) {
var element = createMyElement(); // Тут создаем новый HTML элемент, например, <div>.
element.innerHTML = "<span onclick='func(i)'>some text</span>";
}
По описанным выше причинам при клике на любой элемент будет вызван func(10). Такой простой случай легко фиксится заменой строчки на: "<span onclick='func(" + i + ")'>some text</span>".
Гораздо сложнее, если нам надо передать в функцию не число, а какой-то объект:
for (i = 0; i < 10; ++i) {
var element = createMyElement();
var obj = getMyObject(i); // Тут получаем некий объект сложной природы.
element.innerHTML = "<span onclick='func(obj)'>some text</span>";
}
Опять же при клике на любой из наших элементов вызывается функция от последнего полученного объекта, и ничего удивительного в этом нет.
Вижу некрасивый вариант:
var objects = [];
for (i = 0; i < 10; ++i) {
var element = createMyElement();
var obj = getMyObject(i);
objects.push(obj);
element.innerHTML = "<span onclick='func2(objects, " + i + ")'>some text</span>";
}
где func2 получает список объектов и индекс, по индексу получает нужный. Некрасиво.
Есть идеи, как правильно при создании элемента (вернее даже при создании его внутреннего HTML) связать обработчик события с конкретным текущим значением переменной obj?
Здравствуйте, ezdoctor, Вы писали:
E>Добрый день, E>В Javascript все переменные статические и определены в scope функции, это я знаю. Также знаю, что для захвата локальной переменной (в том ее состоянии, что есть сейчас) можно определить новую функцию, в ней скопировать переменную, тем самым создав новую переменную в другом scope. Тем не менее, пока не получается найти изящного решения практической проблемы.
... E>Есть идеи, как правильно при создании элемента (вернее даже при создании его внутреннего HTML) связать обработчик события с конкретным текущим значением переменной obj?
Стандартно: либо через let, либо вложенную функцию.
Поподробнее, например, здесь: https://github.com/azat-io/you-dont-know-js-ru/blob/master/scope%20%26%20closures/ch5.md
Здравствуйте, ezdoctor, Вы писали:
E>По описанным выше причинам при клике на любой элемент будет вызван func(10). Такой простой случай легко фиксится заменой строчки на: "<span onclick='func(" + i + ")'>some text</span>". E>Гораздо сложнее, если нам надо передать в функцию не число, а какой-то объект: E>for (i = 0; i < 10; ++i) { E> var element = createMyElement(); E> var obj = getMyObject(i); // Тут получаем некий объект сложной природы.
var span = document.createElement('span')
span.onclick = func.bind(null, obj)
span.innerText = 'some text'
element.appendChild(span) E>} E>Опять же при клике на любой из наших элементов вызывается функция от последнего полученного объекта, и ничего удивительного в этом нет.
Здравствуйте, ezdoctor, Вы писали:
E>Добрый день, E>В Javascript все переменные статические и определены в scope функции, это я знаю. Также знаю, что для захвата локальной переменной (в том ее состоянии, что есть сейчас) можно определить новую функцию, в ней скопировать переменную, тем самым создав новую переменную в другом scope. Тем не менее, пока не получается найти изящного решения практической проблемы.
E>Итак, в некой JS функции я прохожусь по циклу и динамически создаю элементы, по одному на итерацию. Например: E>for (i = 0; i < 10; ++i) { E> var element = createMyElement(); // Тут создаем новый HTML элемент, например, <div>. E> element.innerHTML = "<span onclick='func(i)'>some text</span>"; E>}
E>По описанным выше причинам при клике на любой элемент будет вызван func(10). Такой простой случай легко фиксится заменой строчки на: "<span onclick='func(" + i + ")'>some text</span>". E>Гораздо сложнее, если нам надо передать в функцию не число, а какой-то объект: E>for (i = 0; i < 10; ++i) { E> var element = createMyElement(); E> var obj = getMyObject(i); // Тут получаем некий объект сложной природы. E> element.innerHTML = "<span onclick='func(obj)'>some text</span>"; E>} E>Опять же при клике на любой из наших элементов вызывается функция от последнего полученного объекта, и ничего удивительного в этом нет.
E>Вижу некрасивый вариант: E>var objects = []; E>for (i = 0; i < 10; ++i) { E> var element = createMyElement(); E> var obj = getMyObject(i); E> objects.push(obj); E> element.innerHTML = "<span onclick='func2(objects, " + i + ")'>some text</span>"; E>} E>где func2 получает список объектов и индекс, по индексу получает нужный. Некрасиво.
E>Есть идеи, как правильно при создании элемента (вернее даже при создании его внутреннего HTML) связать обработчик события с конкретным текущим значением переменной obj?
function func1(i) {
var obj = getMyObject(i);
func2(obj);
}
for (var i = 0; i < 10; ++i) {
var element = createMyElement();
element.innerHTML = "<span onclick='func1(' + i + ')'>some text</span>";
}