Как мне обновить innerHTML div содержимым массива JS после добавления в него новых элементов?

#javascript #arrays #push

#javascript #массивы #толкать

Вопрос:

У меня есть массив с тремя элементами в нем и четырьмя кнопками — каждая добавляет новый элемент в массив.

Ввод элементов в массив с помощью кнопок работает нормально, но, что касается div, в котором отображаются элементы, он обновляется некорректно. Первый элемент, который я нажимаю, всегда отображается в div правильно, но с этого момента, каждый раз, когда я нажимаю на одну из оставшихся кнопок, отображаются одни и те же элементы.

Что я здесь делаю не так?

JSFiddle

 var inventory = ["Apple", "Pear", "Orange"];

for (i = 0; i < inventory.length; i  )
  document.getElementById("arrayDiv").innerHTML  = inventory[i]   "<br>";

function addItem(newItem, itemBtn) {
  inventory.push(newItem);
  document.getElementById(itemBtn).style.display = "none";
  console.log(inventory);
  document.getElementById("arrayDiv").innerHTML  = inventory[i]   "<br>";
} 
 <p>Fruits:</p>
<div id="arrayDiv"></div>
<hr>
<input id="banana" type="button" value="Banana" onclick="addItem('Banana', 'banana')">
<input id="melon" type="button" value="Melon" onclick="addItem('Melon', 'melon')">
<input id="pineapple" type="button" value="Pineapple" onclick="addItem('Pineapple', 'pineapple')">
<input id="coconut" type="button" value="Coconut" onclick="addItem('Coconut', 'coconut')"> 

Ответ №1:

inventory[i] переменная i фиксируется на одно значение после вашего for loop выполнения.

После того, как цикл печатает [«Яблоко», «Груша», «Оранжевый»], значение i теперь застряло на 3.

(Apple => 0, Pear => 1, Orange => 2), следовательно, следующее значение i равно 3 i из-за for loop

Таким образом, вы можете получить то же название фрукта, отображаемое в HTML.

Чтобы избежать этой проблемы, просто используйте newItem вместо inventory[i] .

 var inventory = ["Apple", "Pear", "Orange"];

for (i = 0; i < inventory.length; i  )
  document.getElementById("arrayDiv").innerHTML  = inventory[i]   "<br>";

function addItem(newItem, itemBtn) {
   
  inventory.push(newItem);
  document.getElementById(itemBtn).style.display = "none";
  
  document.getElementById("arrayDiv").innerHTML  = newItem   "<br>";
} 
 <p>Fruits:</p>
<div id="arrayDiv"></div>
<hr>
<input id="banana" type="button" value="Banana" onclick="addItem('Banana', 'banana')">
<input id="melon" type="button" value="Melon" onclick="addItem('Melon', 'melon')">
<input id="pineapple" type="button" value="Pineapple" onclick="addItem('Pineapple', 'pineapple')">
<input id="coconut" type="button" value="Coconut" onclick="addItem('Coconut', 'coconut')"> 

Ответ №2:

i не меняется, потому что цикл был выполнен (3 — ваша начальная длина массива);

вы можете обновить код, чтобы он искал последний индекс. попробуйте это:

 function addItem(newItem, itemBtn) {
   inventory.push(newItem);
   document.getElementById(itemBtn).style.display = "none";
   var lastItemIndex = inventory.length - 1;
   document.getElementById("arrayDiv").innerHTML  = inventory[lastItemIndex]   "<br>";
}
 

Ответ №3:

В вашем случае индекс i является глобальным. Когда ваш цикл выполнялся в первый раз, цикл завершался, когда i становился 3, и с этого момента он оставался таким. Итак, все, что вы добавите в первый раз, теперь будет иметь это i значение. Теперь всякий раз, когда вы добавляете его снова, элемент, который вы добавили первым, который находится с индексом 3, — это тот, который вы всегда добавляете в dom, но ваш массив будет обновлен правильно, поскольку он не зависел от i значения.

Кроме того, в других ответах будут подходы, которые помогут вам в этом сценарии. Вы также можете попробовать что-то вроде приведенного ниже, используя фрагмент документа и меньше полагаясь на innerHTML бит и больше на DOM API .append , createTextNode например, и т.д.

Единственная причина, по которой этот подход полезен, заключается в том, что количество узлов HTML, отображаемых на экране, зависит от элементов, которые у вас внутри inventory . renderInventory всегда будет работать на основе inventory (например, единого источника истины).

 var inventory = ["Apple", "Pear", "Orange"];

function renderInventory(){
  document.getElementById("arrayDiv").innerHTML = '';
  const df = document.createDocumentFragment();
for (let i = 0; i < inventory.length; i  )
{
   const textNode = document.createTextNode(`${inventory[i]}n`);
   df.append(textNode);
}
document.getElementById("arrayDiv").append(df);
}

function addItem(newItem, itemBtn) {
  inventory.push(newItem);
  document.getElementById(itemBtn).style.display = "none";
  renderInventory();
} 
 #arrayDiv{
white-space:pre
} 
 <p>Fruits:</p>
<div id="arrayDiv"></div>
<hr>
<input id="banana" type="button" value="Banana" onclick="addItem('Banana', 'banana')">
<input id="melon" type="button" value="Melon" onclick="addItem('Melon', 'melon')">
<input id="pineapple" type="button" value="Pineapple" onclick="addItem('Pineapple', 'pineapple')">
<input id="coconut" type="button" value="Coconut" onclick="addItem('Coconut', 'coconut')">