在将新项目推入其中后,如何使用 JS 数组的内容更新 div 的 innerHTML?

How do I update the innerHTML of a div with the contents of a JS array after pushing new items into it?

我有一个数组,其中包含三个项目和四个按钮 - 每个按钮都会向数组添加一个新项目。

使用按钮将项目推入数组工作正常,但是,至于显示项目的 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')">

inventory[i] 变量 i 在你的 for loop 执行后固定为一个值。

在循环打印 ["Apple", "Pear", "Orange"] 后,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')">

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

在您的例子中,索引 i 是全局的。当你的循环 运行 第一次出现时,循环在 i 变为 3 时退出,并且从那以后一直保持这种状态。因此,无论您第一次添加什么,现在都将处于 i 值。现在,每当您再次添加它时,您首先添加的位于索引 3 的项目就是您最终添加到 dom 的项目,但您的数组将正确更新,因为它不依赖于 i值。

此外,其他答案中也会分享一些方法来帮助您解决这种情况。您还可以尝试使用 Document Fragment 并减少对 innerHTML 位的依赖,更多地依赖 DOM API,如 .appendcreateTextNode

此方法有用的唯一原因是 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')">