【问题标题】:Object looping and rendering onto HTML对象循环和渲染成 HTML
【发布时间】:2020-05-19 15:16:24
【问题描述】:

我正在尝试将数据动态呈现到我的 HTML 中,当点击 selectPlayer 时,它应该显示播放器列表的下拉列表并能够选择

选中的同时,统计信息应出现在<div id="stats"></div>

我可以循环遍历对象,但如何将其动态呈现到 HTML 中?

<!DOCTYPE html>
<html lang="en">

<head>
  <link rel="stylesheet" href="./static/style.css" />
  <title>card</title>
</head>

<body>
  <header>
    <h1 id="selectPlayer">Select a player...</h1>
  </header>
  <div id="stats">
    <div id="name"></div>
    <div id="position"></div>
  </div>
  <script>
    const statsData = {
      players: [{
          player: {
            info: {
              positionInfo: "Defender"
            },
            name: {
              first: "Toby",
              last: "Alderweireld"
            },
            currentTeam: {
              name: "Tottenham Hotspur"
            }
          },
          stats: [{
              name: "goals",
              value: 5
            },
            {
              name: "losses",
              value: 20
            },
            {
              name: "wins",
              value: 48
            },
            {
              name: "draws",
              value: 23
            }
          ]
        },
        {
          player: {
            info: {
              positionInfo: "Midfielder"
            },
            name: {
              first: "Yaya",
              last: "Toure"
            },
            currentTeam: {
              name: "Manchester City"
            }
          },
          stats: [{
              name: "goals",
              value: 65
            },
            {
              name: "losses",
              value: 49
            },
            {
              name: "wins",
              value: 149
            },
            {
              name: "draws",
              value: 35
            }
          ]
        },
        {
          player: {
            info: {
              positionInfo: "Attacker"
            },
            name: {
              first: "Riyad",
              last: "Mahrez"
            },
            currentTeam: {
              name: "Leicester City"
            }
          },
          stats: [{
              name: "goals",
              value: 22
            },
            {
              name: "losses",
              value: 23
            },
            {
              name: "wins",
              value: 35
            },
            {
              name: "draws",
              value: 21
            }
          ]
        }
      ]
    };

    document.getElementById(
      "selectPlayer"
    ).innerHTML = `<h1>${statsData.players}<h1>`;
    document.getElementById(
      "stats"
    ).innerHTML = `<h2> ${statsData.player.stats}<h2>`;
  </script>
</body>

</html>

在这里欣赏了不少代码,但似乎有点卡住了

【问题讨论】:

  • 循环是这里的关键,但我们需要知道输出看起来如何才能进一步提供帮助。查看Object.entries 创建一个可迭代对象,查看for...of 循环遍历可迭代对象。
  • 这里不涉及 JSON。 JSON 是一种文本格式,而您只有 JavaScript 对象和数组。
  • 另外,我在您的代码周围添加了一个堆栈片段。单击运行代码 sn -p,您将看到错误显示。对该阵列进行一些研究。您还可以查看问题右侧“相关”列中的一些链接。例如,Loop through an array in JavaScriptHow do I loop through or enumerate a JavaScript object?

标签: javascript html loops object javascript-objects


【解决方案1】:

有很多方法可以解决这个问题 - 一个简单的解决方案是 serialize the JSON to a string,并使用 JSON.stringify() 方法直接在您的文档中显示:

document.getElementById("stats").innerText = JSON.stringify(statsData.players);

const statsData = {
  players: [{
      player: {
        info: {
          positionInfo: "Defender"
        },
        name: {
          first: "Toby",
          last: "Alderweireld"
        },
        currentTeam: {
          name: "Tottenham Hotspur"
        }
      },
      stats: [{
          name: "goals",
          value: 5
        },
        {
          name: "losses",
          value: 20
        },
        {
          name: "wins",
          value: 48
        },
        {
          name: "draws",
          value: 23
        }
      ]
    },
    {
      player: {
        info: {
          positionInfo: "Midfielder"
        },
        name: {
          first: "Yaya",
          last: "Toure"
        },
        currentTeam: {
          name: "Manchester City"
        }
      },
      stats: [{
          name: "goals",
          value: 65
        },
        {
          name: "losses",
          value: 49
        },
        {
          name: "wins",
          value: 149
        },
        {
          name: "draws",
          value: 35
        }
      ]
    },
    {
      player: {
        info: {
          positionInfo: "Attacker"
        },
        name: {
          first: "Riyad",
          last: "Mahrez"
        },
        currentTeam: {
          name: "Leicester City"
        }
      },
      stats: [{
          name: "goals",
          value: 22
        },
        {
          name: "losses",
          value: 23
        },
        {
          name: "wins",
          value: 35
        },
        {
          name: "draws",
          value: 21
        }
      ]
    }
  ]
};

document.getElementById("stats").innerText = JSON.stringify(statsData.players);
<header>
  <h1 id="selectPlayer">Select a player...</h1>
</header>
<div id="stats"></div>

不过,更好的方法是以更易读的方式呈现 JSON 数据。为此,您通常需要在数据集合(数组)上“循环”,对于数组的每个项目,您需要进行一些额外的处理以使数据更具可读性。

例如,您可以执行以下操作以在 HTML 表中显示 JSON 数据:

/* Assuming you've replaced the stats element with a table */
const table = document.getElementById("stats");

/* Loop through each item of statsData object */
statsData.players.forEach(item => {

  /* Extract info and name objects from player (optional) */
  const { info, name } = item.player;

  /* Add row to table for current player */
  const row = table.insertRow();

  /* Add cell for name/position to row */
  const cellName = row.insertCell(0);
  const cellPosition = row.insertCell(1);

  /* Fill each cell with data from current player data */
  cellName.innerText = name.first;
  cellPosition.innerText = info.positionInfo;
});

有关完整的工作示例,请参见下面的代码 sn-p:

const statsData = {
  players: [{
      player: {
        info: {
          positionInfo: "Defender"
        },
        name: {
          first: "Toby",
          last: "Alderweireld"
        },
        currentTeam: {
          name: "Tottenham Hotspur"
        }
      },
      stats: [{
          name: "goals",
          value: 5
        },
        {
          name: "losses",
          value: 20
        },
        {
          name: "wins",
          value: 48
        },
        {
          name: "draws",
          value: 23
        }
      ]
    },
    {
      player: {
        info: {
          positionInfo: "Midfielder"
        },
        name: {
          first: "Yaya",
          last: "Toure"
        },
        currentTeam: {
          name: "Manchester City"
        }
      },
      stats: [{
          name: "goals",
          value: 65
        },
        {
          name: "losses",
          value: 49
        },
        {
          name: "wins",
          value: 149
        },
        {
          name: "draws",
          value: 35
        }
      ]
    },
    {
      player: {
        info: {
          positionInfo: "Attacker"
        },
        name: {
          first: "Riyad",
          last: "Mahrez"
        },
        currentTeam: {
          name: "Leicester City"
        }
      },
      stats: [{
          name: "goals",
          value: 22
        },
        {
          name: "losses",
          value: 23
        },
        {
          name: "wins",
          value: 35
        },
        {
          name: "draws",
          value: 21
        }
      ]
    }
  ]
};

const table = document.getElementById("stats");

/* Loop through each player of statsData object */
statsData.players.forEach(item => {

  /* Extract info and name objects from player (optional) */
  const { info, name } = item.player;
  
  /* Add row to table for current player */
  const row = table.insertRow();
  
  /* Add cell for name/position to row */
  const cellName = row.insertCell(0);
  const cellPosition = row.insertCell(1);
  
  /* Fill each cell with data from current player data */
  cellName.innerText = name.first;
  cellPosition.innerText = info.positionInfo;
});
<header>
  <h1 id="selectPlayer">Select a player...</h1>
</header>
<table id="stats">
  <thead><td>Name</td><td>Position</td></thead>
</table>

希望有帮助!

【讨论】:

    【解决方案2】:

    由于您希望能够选择玩家,请使用&lt;select&gt; 元素。输出该选择元素内的可用玩家。您可以通过为每个玩家创建一个 &lt;option&gt; 元素并将其添加到 select 元素来做到这一点。

    // Loop over each player in the array and use the player and info keys of each player.
    for (const [ index, { player, stats } ] of statsData.players.entries()) {
    
      // Get the name and info of each player.
      const { name, info } = player;
    
      // Get the first and last name out of the name property.
      const { first, last } = name;
    
      // Get the position info out of the info property.
      const { positionInfo } = info;
    
      // Create an option element with the player info available and add it to the select element.
      // The index is the number of position in the players array.
      const html = `<option value="${index}">${first} ${last}</option>`;
      select.insertAdjacentHTML('beforeend', html);
    }
    

    现在玩家可以在列表中选择。如果您要使用您的播放器数据向对象添加另一个播放器,它也会出现在页面加载时的列表中。

    查看下面的 sn-p 以了解实际情况。

    const statsData = {
      players: [{
          player: {
            info: {
              positionInfo: "Defender"
            },
            name: {
              first: "Toby",
              last: "Alderweireld"
            },
            currentTeam: {
              name: "Tottenham Hotspur"
            }
          },
          stats: [{
              name: "goals",
              value: 5
            },
            {
              name: "losses",
              value: 20
            },
            {
              name: "wins",
              value: 48
            },
            {
              name: "draws",
              value: 23
            }
          ]
        },
        {
          player: {
            info: {
              positionInfo: "Midfielder"
            },
            name: {
              first: "Yaya",
              last: "Toure"
            },
            currentTeam: {
              name: "Manchester City"
            }
          },
          stats: [{
              name: "goals",
              value: 65
            },
            {
              name: "losses",
              value: 49
            },
            {
              name: "wins",
              value: 149
            },
            {
              name: "draws",
              value: 35
            }
          ]
        },
        {
          player: {
            info: {
              positionInfo: "Attacker"
            },
            name: {
              first: "Riyad",
              last: "Mahrez"
            },
            currentTeam: {
              name: "Leicester City"
            }
          },
          stats: [{
              name: "goals",
              value: 22
            },
            {
              name: "losses",
              value: 23
            },
            {
              name: "wins",
              value: 35
            },
            {
              name: "draws",
              value: 21
            }
          ]
        }
      ]
    };
    
    const select = document.getElementById('select-player');
    const nameField = document.getElementById('name');
    const positionField = document.getElementById('position');
    const statsList = document.getElementById('stats');
    
    for (const [ index, { player, stats } ] of statsData.players.entries()) {
      const { name } = player;
      const { first, last } = name;
      const html = `<option value="${index}">${first} ${last}</option>`;
      select.insertAdjacentHTML('beforeend', html);
    }
    
    function emptyStatsList() {
      while(statsList.firstElementChild) {
        statsList.removeChild(statsList.firstElementChild);
      }
    }
    
    select.addEventListener('change', function(event) {
      const { target } = event;
      const { value } = target;
      const { player, stats } = statsData.players[value];
      const { name } = player;
      const { first, last } = name;
      nameField.innerText = `${first} ${last}`;
      positionField.innerText = value;
      // Empty stats list.
      emptyStatsList();
      // Loop through the stats array.
      for (const { name, value } of stats) {
        const stat = `<li>${name}: ${value}</li>`;
        statsList.insertAdjacentHTML('beforeend', stat);
      }
    });
    <select id="select-player">
      <option selected hidden value="">Select a player...</option>
    </select>
    
    <div>
      <div id="name"></div>
      <div id="position"></div>
      <ul id="stats"></ul>
    </div>

    【讨论】:

    • 史诗般的工作伙伴,非常感谢您的帮助,很高兴看到您将其组合在一起,现在如果我想添加统计值以在选择玩家后进行渲染,我可以将其添加到事件中听众?
    • 当然。我已修改代码以在选择元素中选择玩家时使用玩家数组中玩家的index 来选择正确的玩家对象。现在您可以在事件侦听器中访问播放器的所有数据。 stats 的值是一个数组,所以输出的时候一定要循环遍历它。
    • 干杯,我现在正试图解决这个问题。我添加了一个新的 HTML ID '外观',现在尝试添加统计监听器。我是否在事件侦听器中编写循环?我可以看到它已经循环通过 statsData 对象?
    • 它只是循环通过statsData将每个玩家添加到&lt;select&gt;元素。在上面的示例中,在事件侦听器内部,它根据 select 元素的 value 选择单个玩家。然后您可以访问该播放器的所有信息,例如当您选择 Toby 时,Toby 的 statsstats 属性是一个数组。因此,要输出该数组中的每个项目,您必须在事件侦听器中对其进行循环并将每个统计信息添加到 HTML。
    • 所以 for 循环将类似于上面循环统计数据的循环,而不是添加玩家,它将添加统计数据。这是我在 EventsListener 中的循环,但它给了我一个错误,即 stats 的名称未定义。
    猜你喜欢
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    相关资源
    最近更新 更多