Я не понимаю, почему после перехода по ссылке показывается "undefined". Кто-нибудь знает, почему?
let allBlocks = ["one","two"];
for (i = 0; i < allBlocks.length; i++) {
document.body.innerHTML += '<p id = "" onclick = "test(allBlocks[i])">Link</p>';
}
function test(n){
alert(n);
}
Даже i
находится в глобальной области видимости после того, как значение цикла i
будет длиной массива, поэтому оно будет похоже на array[array.length]
, которое будет undefined
. Чтобы заставить его работать, добавьте значение i
в этой точке вместе со строкой.
let allBlocks = ["one", "two"];
for (i = 0; i < allBlocks.length; i++) {
document.body.innerHTML += `<p id = "" onclick = "test(allBlocks[${i}])">Link</p>`;
}
function test(n) {
alert(n);
}
Или, если массив не находится в глобальной области видимости, вам нужно добавить само значение в качестве строкового аргумента (заключить в кавычки).
let allBlocks = ["one", "two"];
for (i = 0; i < allBlocks.length; i++) {
document.body.innerHTML += `<p id = "" onclick = "test('${allBlocks[i]}')">Link</p>`;
}
function test(n) {
alert(n);
}
К вашему сведению:document.body.innerHTML +=...
— действительно плохая идея, поскольку она всегда будет воссоздавать элементы DOM, которые удалят любой прикрепленный обработчик событий, свойства и т. д. Поэтому всегда сохраняйте переменную в цикле, чтобы сохранить строку HTML, а затем, наконец, обновить содержимое (в вашем случае ).
Возможно, вам нужна интерполяция строк
for (i = 0; i < allBlocks.length; i++) {
document.body.innerHTML += `<p id = "" onclick = "test(${allBlocks[i]})">Link</p>`;
}
function test(n){
alert(n);
}
Это передаст значение allblocks[i]
вместо строки
..потому что allBlocks[i]
не определено. Вам нужно, чтобы значение i
отображалось в вашем HTML.
let allBlocks = ["one","two"];
for (i = 0; i < allBlocks.length; i++) {
document.body.innerHTML += '<p id = "" onclick = "test(allBlocks['+i+'])">Link</p>';
}
function test(n){
alert(n);
}
Поскольку ваш код в обработчике кликов
test(allBlocks[i])
Похоже, ваш код находится в глобальной области видимости, и это единственная причина, по которой он не выдает ошибку. Когда происходит щелчок, i
имеет значение allBlocks.length
, которое находится за концом массива. Доступ к элементу массива, которого нет, приводит к undefined
.
Минимальное изменение заключается в использовании конкатенации строк для помещения значения i
в обработчик кликов, а не i
:
document.body.innerHTML += '<p id = "" onclick = "test(allBlocks[' + i + '])">Link</p>';
Однако вместо этого я бы предложил современную обработку событий через addEventListener
:
for (let i = 0; i < allBlocks.length; i++) {
// ^^^---- Note
const p = document.createElement("p");
p.textContent = "Link";
p.addEventListener("click", test.bind(null, allBlocks[i]));
document.body.appendChild(p);
}
Примечание: element.innerHTML += ...
никогда не бывает хорошей идеей. Это заставляет браузер перебирать все содержимое element
, создавая строку HTML для содержащейся в ней структуры DOM, а затем передавать эту строку на уровень JavaScript; затем уровень JavaScript должен добавить строку и передать ее обратно в браузер; затем браузер должен проанализировать HTML, создать кучу новых замещающих элементов, стереть содержимое element
и заменить его этими новыми элементами. Помимо большого количества ненужной работы, он также уничтожает любые обработчики событий для элементов, любую информацию о состоянии и т. д.
i
действует как глобальная переменная. Также вы можете использовать литералы шаблонов
let allBlocks = ["one", "two"];
for (let i = 0; i < allBlocks.length; i++) {
document.body.innerHTML += `<p id = "" onclick = "test(allBlocks[${i}])">Link</p>`;
}
function test(n) {
alert(n);
}
теперь это работает! Я думал, что проблема в масштабе, но я все еще учусь :) Спасибо!