用 JS 循环中的值填充 HTML table

Fill HTML table with values from JS loop

我希望我的 table 'scores' 由对象中保存的 'ability' 值填充。

我认为我的问题在于以下几行:

var player = document.getElementById("player" + i + 1);
playerscore.innerText = playerList[i].ability;

我可以通过不使用 'i' 的值来递增 ID 来实现它,我只需为每个 ID 编写一行代码。我确信这不是最好的做事方式,因此我想使用已经设置的循环循环访问 ID。

我的代码哪里出错了,更好的方法是什么?

提前致谢。

var playerList = [
  {name: "player1", highScore: 1, ability: 8},
  {name: "player2", highScore: 1, ability: 7},
  {name: "player3", highScore: 1, ability: 6},
  {name: "player4", highScore: 1, ability: 5},
  {name: "player5", highScore: 1, ability: 4},
  {name: "player6", highScore: 1, ability: 3},
  {name: "player7", highScore: 1, ability: 2},
  {name: "player8", highScore: 1, ability: 1}
];

for (var i = 0; i < playerList.length; i++) {
  console.log(i);
  var player = document.getElementById("player" + i + 1);
  var playerscore = document.getElementById('player' + i + 1 + "score")
  var progress=Math.random();
  progress=11*progress;
  progress=Math.floor(progress);
  playerList[i].ability=playerList[i].ability+progress;
  console.log(playerList[i])

  //add players score to the table//

  playerscore.innerText = playerList[i].ability;

}
<table>
    <tr>
        <th>Player</th>
        <th>Score</th>
    </tr>
    <tr>
        <td id="player1">1</td>
        <td id="player1score">0</td>
    </tr>
    <tr>
        <td id="player2">2</td>
        <td id="player2score">0</td>
    </tr>
    <tr>
        <td id="player3">3</td>
        <td id="player3score">0</td>
    </tr>
    <tr>
        <td id="player4">4</td>
        <td id="player4score">0</td>
    </tr>
    <tr>
        <td id="player5">5</td>
        <td id="player5score">0</td>
    </tr>
    <tr>
        <td id="player6">6</td>
        <td id="player6score">0</td>
    </tr>
    <tr>
        <td id="player7">7</td>
        <td id="player7score">0</td>
    </tr>
    <tr>
        <td id="player8">8</td>
        <td id="player8score">0</td>
    </tr>
</table>

i + 1 括在 getElementById 的括号中 - 请参阅下面的演示:

var playerList = [
{name: "player1", highScore: 1, ability: 8},
{name: "player2", highScore: 1, ability: 7},
{name: "player3", highScore: 1, ability: 6},
{name: "player4", highScore: 1, ability: 5},
{name: "player5", highScore: 1, ability: 4},
{name: "player6", highScore: 1, ability: 3},
{name: "player7", highScore: 1, ability: 2},
{name: "player8", highScore: 1, ability: 1}
];

    for (var i = 0; i < playerList.length; i++) {
            var player = document.getElementById("player" + (i + 1));
            var playerscore = document.getElementById('player' + (i + 1) + "score")
    var progress=Math.random();
    progress=11*progress;
    progress=Math.floor(progress);
    playerList[i].ability=playerList[i].ability+progress;

            //add players score to the table//

            playerscore.innerText = playerList[i].ability;

    }
<table>
  <tr>
    <th>Player</th>
    <th>Score</th>
  </tr>
  <tr>
    <td id="player1">1</td>
    <td id="player1score">0</td>
  </tr>
  <tr>
    <td id="player2">2</td>
    <td id="player2score">0</td>
  </tr>
  <tr>
    <td id="player3">3</td>
    <td id="player3score">0</td>
  </tr>
  <tr>
    <td id="player4">4</td>
    <td id="player4score">0</td>
  </tr>
  <tr>
    <td id="player5">5</td>
    <td id="player5score">0</td>
  </tr>
  <tr>
    <td id="player6">6</td>
    <td id="player6score">0</td>
  </tr>
  <tr>
    <td id="player7">7</td>
    <td id="player7score">0</td>
  </tr>
  <tr>
    <td id="player8">8</td>
    <td id="player8score">0</td>
  </tr>
</table>

var playerList = [
  {name: "player1", highScore: 1, ability: 8},
  {name: "player2", highScore: 1, ability: 7},
  {name: "player3", highScore: 1, ability: 6},
  {name: "player4", highScore: 1, ability: 5},
  {name: "player5", highScore: 1, ability: 4},
  {name: "player6", highScore: 1, ability: 3},
  {name: "player7", highScore: 1, ability: 2},
  {name: "player8", highScore: 1, ability: 1}
];

for (var i = 0; i < playerList.length; i++) {
  console.log(i);
  var player = document.getElementById("player" + (i + 1));
  var playerscore = document.getElementById('player' + (i + 1) + "score")
  var progress=Math.random();
  progress=11*progress;
  progress=Math.floor(progress);
  playerList[i].ability=playerList[i].ability+progress;
  console.log(playerList[i])

  //add players score to the table//

  playerscore.innerText = playerList[i].ability;

}
<table>
    <tr>
        <th>Player</th>
        <th>Score</th>
    </tr>
    <tr>
        <td id="player1">1</td>
        <td id="player1score">0</td>
    </tr>
    <tr>
        <td id="player2">2</td>
        <td id="player2score">0</td>
    </tr>
    <tr>
        <td id="player3">3</td>
        <td id="player3score">0</td>
    </tr>
    <tr>
        <td id="player4">4</td>
        <td id="player4score">0</td>
    </tr>
    <tr>
        <td id="player5">5</td>
        <td id="player5score">0</td>
    </tr>
    <tr>
        <td id="player6">6</td>
        <td id="player6score">0</td>
    </tr>
    <tr>
        <td id="player7">7</td>
        <td id="player7score">0</td>
    </tr>
    <tr>
        <td id="player8">8</td>
        <td id="player8score">0</td>
    </tr>
</table>

你的连接有问题,假设 i=0,所以这个 "player" + i + 1 = player01 所以让 player1 像这样使用 "player" + (i + 1) 。这将首先评估括号然后将与字符串连接。

"player" + i + 1 的结果不会像预期的那样。您可以将 i + 1 存储在变量中并在 getElementById() 中使用它。

var index = i + 1;
var player = document.getElementById("player" + index);
var playerscore = document.getElementById('player' + index + "score")

Here 是工作中的 jsfiddle。

您最初的问题是您没有正确取消对计数变量的引用,因此计算出不正确的索引以用于字符串连接。

要解决此问题,您需要将 "i + 1" 表达式放入 getElementById 调用中的一组普通括号中。

基本上你的初次通话:

var player = document.getElementById("player" + i + 1);

需要成为:

var player = document.getElementById("player" + (i + 1));

在以前的版本中,效果是最后的 1 变成了字符串,从而成为字符串的一部分,而不是像预期的那样添加到索引中。

一个更好的方法来做你在 vanilla JS 中尝试的事情是跳过所有这些 +1 的事情,让你的代码可重用。

如果您按照 W3C 的建议格式化您的 table,那么您最终会得到如下内容:

<table id="myTable">
  <thead>
    <tr>
      <th>Player</th>
      <th>Score</th>
    </tr>
  </thead>
  <tbody id="myTableBody">
    <tr>
      <td>Player 1</td>
      <td>1</td>
    </tr>
    <tr>
      <td>Player 2</td>
      <td>2</td>
    </tr>
    <!-- More TR's here as needed -->
  </tbody>
</table>

使用 theadtbody 意味着您可以分别操作 table 的页眉和正文部分,然后允许您使用底层 JS api 和 table 属性,而不必执行构建字符串并可能导致该字符串格式错误的风险步骤。

我并不是说构建字符串的方法是错误的,但它很容易出错,正如您所看到的,只需一个小的计算错误,您就会得到一个 ID 名称不匹配任何内容。

在 JavaScript 的程序控制下向 table 添加行非常简单,如下所示:

function addRow(playerName, playerScore)
{
  var tableBody = document.getElementById('myTableBody');
  var newRow = tableBody.insertRow(tableBody.rows.length);
  var nameCell = newRow.insertCell(0);
  var scoreCell = newRow.insertCell(1);
  var playerText = document.createTextNode(playerName);
  var scoreText = document.createTextNode(playerScore);
  nameCell.appendChild(playerText);
  scoreCell.appendChild(scoreText);
}

这会将新行添加到 table body.Removing 的末尾,按索引一行就这么简单:

function removeRow(rowNumber)
{
  var tableBody = document.getElementById('myTableBody');
  tableBody.deleteRow(rowNumber);
}

需要记住的 重要 一点是,一旦您删除了一行,其余的行就会向上移动以取代它。这意味着如果您删除第一个(第 0 行),那么完成后,1 将变为 0,2 将变为 1,3 将变为 2 等等。

这意味着如果你想删除前两个,你需要删除索引 0 两次,而不是你可能认为的 0 和 1。

至于将您的数据数组添加到 table,使用添加函数现在变得非常简单:

playerList.forEach(function(listItem){
  addRow(listItem.name, listItem.ability)
});

如果您需要更改实际的文本数据,只需执行以下操作即可:

function changePlayerName(rowNumber, playerName)
{
  var tableBody = document.getElementById('myTableBody');
  tableBody.Rows[rowNumber].cells[0].innerText = playerName;
}

function changePlayerScore(rowNumber, playerScore)
{
  var tableBody = document.getElementById('myTableBody');
  tableBody.Rows[rowNumber].cells[1].innerText = playerScore;
}

以这种方式做事,可以使您的代码整洁且易于阅读和理解。当你一个月后再回来看它时,你仍然能够理解你在努力实现什么,它会帮助你学习。

还有许多其他方法可以做到这一点。您可以像在原始版本中一样在所有标签上放置 ID,然后通过字符串连接引用这些标签,您使用的方法,您可以使用带有行 ID 的 class 选择器来定位实际的直接元素,您也可以使用 JQuery。

但是,如果您正在为看起来像游戏的东西构建复杂的 UI,那么我强烈建议您考虑使用现代 UI 构建系统,例如 'Aurelia'或 'Angular' ,两者都使用较新的 JS2016/2017 语法,允许您编写真正干净的代码,具有易于理解的结构,如 "for loops" 、 "repeat loops" 和所有其他不错的功能现代 JavaScript 带来。也不必担心与现代 UI 框架的向后可比性,因为它们中的大多数将构建与旧浏览器兼容的代码。

虽然我坚信像您在这项任务中一样使用香草 JavaScript,但如果存在这种可能性,我也相信让任务更容易。