Я не понимаю, почему после перехода по ссылке вместо переданного аргумента отображается "undefined"

Я не понимаю, почему после перехода по ссылке показывается "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);
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
72
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Даже 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, а затем, наконец, обновить содержимое (в вашем случае ).

теперь это работает! Я думал, что проблема в масштабе, но я все еще учусь :) Спасибо!

Tomkowaty 10.04.2019 19:24

Возможно, вам нужна интерполяция строк

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);
}

Другие вопросы по теме