创建这个动态生成的表时我做错了啥?

Posted

技术标签:

【中文标题】创建这个动态生成的表时我做错了啥?【英文标题】:What am I doing wrong in creating this dynamically generated table?创建这个动态生成的表时我做错了什么? 【发布时间】:2022-01-19 03:18:47 【问题描述】:

对于任何简单的错误,我深表歉意,这是我的第一篇 Stack Overflow 帖子,我对编码比较陌生。

我正在尝试创建一个使用 DOM 元素显示动态生成的表格的网站。此表的行和列已使用 DOM 元素定义,现在应该在从 initialize() 调用 storeItemOutput() 时在页面加载时自行填充。它应该通过先前定义和填充的数组 storeItems 从循环中提取数据,并在表 id“storeItemOutput”中显示它们的属性。它还应该从下拉框中获取五个值之一,并在更改时显示与所选类别匹配的项目。

但是,我无法获取表格本身或其内容以实际显示在页面上。我不确定是什么阻止了这种情况,而且没有任何输出让我很困惑。我的函数中是否缺少一些代码?表创建不正确?

我在下面包含了我的部分代码,以及预期输出和实际输出,以帮助您理解我的问题。

<select class="categoryDropDown" style="margin: 30px;">
  <p>
    <option selected value="All" onload="storeItemOutput();">All</option>
    <option value="Tops" onchange="storeItemOutput();">Tops</option>
    <option value="Bottoms" onchange="storeItemOutput();">Bottoms</option>
    <option value="Shoes" onchange="storeItemOutput();">Shoes</option>
    <option value="Accessories" onchange="storeItemOutput();">Accessories</option>
  </p>
</select>

<table id="storeItemOutput">
  <span><strong>| ID | Product Name | Price | Qty | Max | Category | Image |</strong></span>
  </br>
  <tbody>
    <tr>
      <th>b</th>
      <th>b</th>
      <th>b</th>
      <th>b</th>
      <th>b</th>
      <th>b</th>
      <th>b</th>
    </tr>
    <tr>
      <td>b</td>
      <td>b</td>
      <td>b</td>
      <td>b</td>
      <td>b</td>
      <td>b</td>
      <td>b</td>
    </tr>
  </tbody>
  (Output all store items via DOM table here)
</table>

这是我的一些 html 代码,带有一个带有 ID 的虚拟表和一个下拉菜单类。

var storeItems = [];

function StoreItem(id, name, price, qtyOnHand, maxPerCust, category, shipping, reviews, description, image) 
  this.id = id; //String
  this.name = name; //String
  this.price = price; //Number
  this.qtyOnHand = qtyOnHand; //Number
  this.maxPerCust = maxPerCust; //Number
  this.category = category; //String
  this.shipping = shipping; //Number
  this.reviews = reviews; //Array
  this.description = description; //String
  this.image = image; //String


storeItems.push(new StoreItem("Y2k111", "Black Hoodie", 119.99, 10, 1, "Tops", 19.99, this.reviews, "100% Cotton Hoodie in Black", "/img/home_img/link"));

一些 javascript 代码为商店项目创建一个空数组,为商店项目创建一个对象构造函数,并将一个新项目推送到数组中(通常有多个项目被推送,我在这里只使用了一个以节省空间)。

function storeItemOutput() 
  var itemTableDiv = document.getElementById("cartItemOutput");
  var table = document.createElement("table");

  itemTableDiv.innerHTML = "";

  document.getElementsByTagName("tbody")[0].remove();

  var tBody = document.createElement("tbody");

  var headerRow = document.createElement("tr");
  var hC1 = document.createElement("th");
  var hC2 = document.createElement("th");
  var hC3 = document.createElement("th");
  var hC4 = document.createElement("th");
  var hC5 = document.createElement("th");
  var hC6 = document.createElement("th");
  var hC7 = document.createElement("th");

  hC1.innerHTML = "Item ID";
  hC2.innerHTML = "Item Name";
  hC3.innerHTML = "Item Price";
  hC4.innerHTML = "Item Quantity";
  hC5.innerHTML = "Max Items Per Customer";
  hC6.innerHTML = "Category";
  hC7.innerHTML = "Image";

  headerRow.appendChild(hC1);
  headerRow.appendChild(hC2);
  headerRow.appendChild(hC3);
  headerRow.appendChild(hC4);
  headerRow.appendChild(hC5);
  headerRow.appendChild(hC6);
  headerRow.appendChild(hC7);

  tbody.appendChild(headerRow);

  for (var index = 0; index < storeItems.length; index++) 
    var products = storeItems[i];

    var theRow = document.createElement("tr");

    var c1 = document.createElement("td");
    var c2 = document.createElement("td");
    var c3 = document.createElement("td");
    var c4 = document.createElement("td");
    var c5 = document.createElement("td");
    var c6 = document.createElement("td");
    var c7 = document.createElement("td");

    c1.innerHTML = products.id;
    c2.innerHTML = products.name;
    c3.innerHTML = "$" + products.price.toFixed(2);
    c4.innerHTML = products.qtyOnHand;
    c5.innerHTML = products.maxPerCust;
    c6.innerHTML = products.category;
    c7.innerHTML = products.image;

    theRow.appendChild(c1);
    theRow.appendChild(c2);
    theRow.appendChild(c3);
    theRow.appendChild(c4);
    theRow.appendChild(c5);
    theRow.appendChild(c6);
    theRow.appendChild(c7);

    tbody.appendChild(theRow);
  
  itemTableDiv.appendChild(tbody);

  var selectedCategory = document.getElementByClass("categoryDropDown").value;
  var filteredItems = [];
  var index = 0;
  while (index < storeItems.length) 
    if (storeItems[index].category == selectedCategory) 
      filteredItems.push(storeItems[index]);
    

    index++;
  

  storeItemOutput(filteredItems);

最后,我的功能是在显示与所选类别匹配的项目之前创建和填充表格。

这是表格应该是什么样子的图像:

working table

而且我的表缺少输出:

my missing table

任何帮助将不胜感激。

【问题讨论】:

Span 不是表的子表。 好的,经过审查,我意识到我不需要表格的跨度,因为应该使用 DOM 创建标题行。因此,跨度现在消失了。还有什么? 【参考方案1】:

这是一个工作示例。有几点值得一提:

我使用了一个模板元素,因为它会重复创建 类似的内容要快得多。 浮点数学存在舍入错误。出于这个原因,我存储了 以美分而不是美元为单位的价格。对数字执行所有数学运算 美分,然后以美元和美分表示 NodeList 与数组非常相似,但略有不同。例如,它没有forEach 成员函数。出于这个原因,我在 appendRow 函数中使用了Array.from。 (如果您使用注释代码,实际上会缩短 1 行)

"use strict";

function newEl(tag) 
  return document.createElement(tag)


function byId(id) 
  return document.getElementById(id)


function qs(sel, parent = document) 
  return parent.querySelector(sel)


function qsa(sel, parent = document) 
  return parent.querySelectorAll(sel)

window.addEventListener('load', onLoaded, false);

function onLoaded(evt) 
  var tableData = [
    ["PID01", "Fluffy Bear", 599, 600, 20, "Toy", "bear.png"],
    ["PID02", "Rubber Ducky", 1599, 40, 5, "Toy", "duck.png"],
    ["PID03", "Cool Handbag", 599, 1, 2, "Fashion", "bag.png"],
    ["PID04", "Fidget Spinner", 999, 120, 10, "Toy", "spinner.png"],
    ["PID05", "Lame Handbag", 4599, 60, 3, "Fashion", "bag.png"],
    ["PID06", "UltraMega Genuine Laptop", 170599, 20, 2, "Technology", "laptop.png"],
  ];
  populateTable(tableData);

  var categoryNames = ["All", "Fashion", "Toy", "Technology"];
  populateSelect(byId('catSelector'), categoryNames);

  qs('select').addEventListener('change', updateFilter, false);


function populateSelect(selElem, data) 
  selElem.innerHTML = '';
  data.forEach(txt => selElem.appendChild(new Option(txt, txt)));


function populateTable(data) 
  data.forEach(appendRow);

  function appendRow(itemData, itemIndex, items) 
    let newRow = byId('productRowTemplate').content.cloneNode(true);
    let cells = Array.from(newRow.firstChild.cells);
    cells.forEach((cell, index) => 
      if (index == 2)
        cell.textContent = '$' + (itemData[index] / 100).toFixed(2);
      else
        cell.textContent = itemData[index];
    );
    //      cells[0].textContent = itemData[0];
    //      cells[1].textContent = itemData[1];
    //      cells[2].textContent = '$'+(itemData[2]/100).toFixed(2);
    //      cells[3].textContent = itemData[3];
    //      cells[4].textContent = itemData[4];
    //      cells[5].textContent = itemData[5];
    byId('storeItemOutput').tBodies[0].appendChild(newRow);
  


function updateFilter() 
  let filter = byId('catSelector').value;
  let prodRows = qsa('#storeItemOutput > tbody > tr');

  if (filter == 'All') 
    prodRows.forEach(row => row.classList.remove('notShown'));
   else 
    prodRows.forEach(
      row => 
        if (row.cells[5].textContent == filter)
          row.classList.remove('notShown');
        else
          row.classList.add('notShown');
      
    );
  
.notShown 
  display: none;


.price,
.qty,
.max 
  text-align: right;
<template id='productRowTemplate'><tr>
        <td class='id'></td>
        <td class='name'></td>
        <td class='price'></td>
        <td class='qty'></td>
        <td class='max'></td>
        <td class='cat'></td>
        <td><img class='icon'/></td>
    </tr></template>

<body>
  Filter:
  <select id='catSelector'></select>
  <table id='storeItemOutput'>
    <thead>
      <tr>
        <th>ID</th>
        <th>Product</th>
        <th>Price</th>
        <th>Qty</th>
        <th>Max</th>
        <th>Category</th>
        <th>Image</th>
      </tr>
    </thead>
    <tbody>
    </tbody>
  </table>
</body>

【讨论】:

以上是关于创建这个动态生成的表时我做错了啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用`setVariables`后中继生成无效查询-我做错了啥吗?

iOS推送通知我做错了啥? [关闭]

试图设置背景图片,但 div id 名称没有显示在后面的代码中,我做错了啥?

这个Lua代码我做错了啥

使用回溯创建给定列表的排列列表:我做错了啥?

这个简单的模板类我做错了啥?