【问题标题】:HTML table columns are not showing up properlyHTML 表格列未正确显示
【发布时间】:2026-01-24 12:00:02
【问题描述】:

我有一个任务来动态显示我已经完成的 HTML 表格行,我有一个 thead,tbodytfoot,这三个都在不同的不同表格中,因为我想让 tbody 滚动达到一定高度后

表格说明

  • 在第一个表中我只有thead,最后一个我只有tfoot,它正在计算一些总数
  • 主要是第二个,这是动态创建的,当页面加载时,会创建第一行,其输入字段为Cells
  • 有些输入字段是可编辑的,有些则不是因为要求
  • 行中的最后一个输入字段是Disc%,如果用户按下回车,我正在创建新行,每行的第一个单元格是ItemName,这是 Jquery 自动完成功能,因此用户正在输入一些内容并选择一些 itemName 并打开按选项卡我正在相应地填充一些字段

我要做什么

  • 第二张桌子有tbody,我给了它一些高度和overflow:auto,以便它在一定高度后滚动

  • 问题是所有的列都没有统一对齐,甚至我已经分别给它们设置了样式

  • 当 Scroll 到来时,tbody 也在缩小,即使它们都在同一个 div

代码

function format(number, decimals = 2) {
  const fixed = parseFloat(number).toFixed(decimals);
  const [float, dec] = fixed.split('.')
  const intFormatted = (+float)
  return intFormatted + (dec ? '.' + dec : '');
}


$(document).ready(function() {


  var tableData = {};
  var tabledata = {
    "ALMOND CHBAR~2402": {
      "itemName": "ALMOND CHBAR",
      "itemCode": "2402",
      "costPrice": 20.0,
      "gstPercentage": 14.5,
      "unitCode": "NOS",
      "mrp": 30.0
    },
    "A BR SB EX~333": {
      "itemName": "A BR SB EX",
      "itemCode": "333",
      "costPrice": 1.0,
      "gstPercentage": 0.0,
      "unitCode": "NOS",
      "mrp": 1.0
    }
  }

  populateData(tabledata)

  function rowappendThead(thead) {

    const theadymarkup =
      `<tr>
									<th id="itemNameth" class="commanth">Item Name</th>
									<th id="itemCodeth" class="commanth">I Code</th>
									<th id="mrpth" class="commanth">MRP</th>
									<th id="purRateth" class="commanth">Price</th>
									<th id="unitQtyth" class="commanth">Unit Qty</th>
									<th id="discPercentageth" class="commanth">Disc %</th>
									<th id="discAmtth" class="commanth">Disc Amt</th>
									<th id="gstPercentageth" class="commanth">GST %</th>
									<th id="gstAmtth" class="commanth">GST Amt</th>
									<th id="totalAmtth" class="commanth">Total Amt</th>
									<th style="background-color: white;border: 1px solid white"></th> 

								</tr>`

    $(thead).append(theadymarkup);

  }

  function rowappend(tbody) {

    const markup =
      `<tr>
											  <td>
											    <input type="text" class="form-control commanChange" id="itemNametd" name="itemNametd">
											  </td>
											  <td><input type="text" name="itemCodetd" id="itemCodetd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
											  <td><input type="text" name="mrptd" id="mrptd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
											  <td><input type="tel"  id="purRatetd"  class="form-control commantd"name="purRatetd"></td>
											  <td>
											    <input type="tel" id="unitQtytd"class="form-control commanChange" name="unitQtytd">
											  </td>
								               			 
											  <td>
											    <input type="tel" id="discPercentagetd"class="form-control commanChange" name="discPercentagetd" value="0.00">
											  </td>
											  <td><input type="text" name="discAmttd" id="discAmttd" class="form-control commantd" readonly="readonly" tabindex="-1"></td> 
											  <td><input type="text" name="gstPercentagetd" id="gstPercentagetd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
											  <td><input type="text" name="gstAmttd" id="gstAmttd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
											  <td><input type="text" name="totalAmttd" id="totalAmttd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
											  <input type="hidden" name="unittd" id="unittd" class="form-control commantd">
											  <td style="background-color: white;border: 1px white"><i class="fas fa-times fa-2x remove-btn" ></i></td>
											  
											</tr>`

    $(tbody).append(markup);
    setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

    var autoCompleteData = Object.keys(tableData);
    $("[name=itemNametd]", tbody).last().autocomplete({
      source: autoCompleteData,
      autoSelectFirst: true,
      autoFocus: true

    }).data('tableData', tableData);


  }

  function rowappendTfoot(tfoot) {

    const tfootmarkup =
      `<tr>
	<td id="itemNametf" class="commantf" align="center">Total ->
	</td>
	<td id="itemCodetf" class="commantf"></td>
	<td id="mrptf" class="commantd"></td>
	<td id="purRatetf" class="commantf"></td>
	<td id="unitQtytf" class="commantf"></td>
	<td id="discPercentagetf" class="commantf"></td>	
	<td id="discAmttf" class="commantf"></td>
	<td id="gstPercentagetf" class="commantf"></td>
	<td id="gstAmttf" class="commantf"></td>
	<td id="totalAmttf" class="commantf"></td>
	<td id="crossBtntf" class="commantf"><span class="rupee"></span></td>
</tr>`

    $(tfoot).append(tfootmarkup);

  }

  function getValues(row) {
    const search = ($('[name=itemNametd]', row).val()).toString()

    var data = $('[name=itemNametd]', row).data('tableData');
    const value = data[search];

    if (value) {
      CostPrice = value.costPrice;
      $(row).find("[name=itemCodetd]").val(value.itemCode);
      $(row).find("[name=mrptd]").val(format(value.mrp));
      $(row).find("[name=purRatetd]").val(format(CostPrice));
      $(row).find("[name=unittd]").val(value.unitCode);
      $(row).find("[name=gstPercentagetd]").val(value.gstPercentage);
      $("[name=purRatetd]").focus();
    }

  }


  document.addEventListener("keydown", function(e) {
    const row = event.target.parentElement.parentElement

    var keycode = event.keyCode || event.which;
    if (keycode == '13') {
      if (!$(event.target).val()) {
        e.preventDefault();
        return;
      }
      const row = e.target.parentElement.parentElement
      if (event.target.matches('[name=discPercentagetd]')) {
        if ($(row).parent().find('tr').length - $(row).index() === 1) {
          rowappend(event.target.parentElement.parentElement.parentElement)
        }
      }
    }

  });

  $(document).on("focusout", "[name=itemNametd]", function(e) {
    const row = e.target.parentElement.parentElement
    getValues(e.target.parentElement.parentElement)
  });

  function populateData(data) {
    tableData = Object.assign({}, data);
    var autoCompleteData = Object.keys(data);
    rowappendThead($('thead', '#tableInvoice'));
    rowappend($('tbody', '#tbodyScroll'));
    rowappendTfoot($('tfoot', '#tfootTable'));

  }




});
input[type=tel] {
  text-align: right;
}

#itemNameth {
  width: 370px;
}

#itemNametd {
  width: 398px;
}

#itemNametf {
  width: 348px;
}

#itemCodetf,
#itemCodetd,
#mrptf,
#mrptd,
#purRatetf,
#purRatetd,
#discAmttf,
#discAmttd,
#gstAmttf,
#gstAmttd,
#gstPercentagetf,
#gstPercentagetd,
#unitQtytd,
#discPercentagetd,
#unitQtytf,
#discPercentagetf {
  font-size: 10pt;
  color: black;
  text-align: right;
}

#itemCodeth {
  width: 60px;
}

#itemCodetf {
  width: 57px;
}

#itemCodetd {
  width: 63px;
}

#unitQtyth {
  width: 60px;
}

#unitQtytf {
  width: 60px;
}

#unitQtytd {
  width: 60px;
}

#discPercentagetd {
  width: 60px;
}

#discPercentageth {
  width: 60px;
}

#discPercentagetf {
  width: 60px;
}

#mrpth {
  width: 60px;
}

#mrptf {
  width: 55px;
}

#mrptd {
  width: 63px;
}

#purRateth {
  width: 70px;
}

#purRatetf {
  width: 65px;
}

#purRatetd {
  width: 73px;
}

#discAmtth {
  width: 70px;
}

#discAmttf {
  width: 70px;
}

#discAmttd {
  width: 70px;
}

#gstAmtth {
  width: 80px;
}

#gstAmttf {
  width: 80px;
}

#gstAmttd {
  width: 80px;
}

#gstPercentageth {
  width: 40px;
}

#gstPercentagetf {
  width: 60px;
}

#gstPercentagetd {
  width: 60px;
}

#totalAmttd {
  width: 130px;
  font-size: 10pt;
  color: black;
  font-weight: bold;
  text-align: right;
  background-color: #C4B7C7;
}

#totalAmttf {
  width: 105px;
  font-size: 10pt;
  color: black;
  font-weight: bold;
  text-align: right;
  background-color: #C4B7C7;
}

#totalAmtth {
  width: 130px;
}

#itemNametd {
  font-size: 10pt;
}

#crossBtntf {
  width: 25px;
  background-color: white;
  border: 1px white;
}

#itemNametf,
#totalAmttf {
  color: black;
  font-weight: bold;
}

table {
  border-collapse: collapse !important;
}

table.table-bordered>thead>tr>th {
  border: 1px solid white;
  white-space: nowrap;
  font-family: Verdana;
  font-size: 9pt;
  padding: 0px 5px 5px 5px;
  background-color: rgba(29, 150, 178, 1);
  font-weight: normal;
  text-align: center;
  color: white;
}

table.table-bordered>tbody>tr>td {
  border: 1px solid rgba(29, 150, 178, 1);
  white-space: nowrap;
  font-family: Verdana;
  font-size: 8pt;
  background-color: rgba(84, 83, 72, .1);
  padding: 0px 5px 5px 5px;
  color: black;
}

table.table-bordered>tfoot>tr>td {
  border: 1px solid black;
  white-space: nowrap;
  border-collapse: separate !important;
  font-family: Verdana;
  font-size: 8pt;
  background-color: #8c8edf;
  padding: 0px 5px 5px 5px;
}
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="row tableGrn">
  <div id="printFull">
    <div align="right">
      <table class="table table-bordered" id="tableInvoice">
        <thead>

        </thead>


      </table>
      <div style="height: 30px; overflow-y: auto;">
        <table id="tbodyScroll">
          <thead>
          </thead>
          <tbody>
          </tbody>
        </table>
      </div>

    </div>
  </div>

  <div class="row">
    <table class="table table-bordered" id="tfootTable">
      <tbody>

      </tbody>
      <tfoot>


      </tfoot>
    </table>
  </div>
</div>

它是这样显示的:

我认为我在 CSS 上搞砸了很多,而宽度与 % 一样,它是重叠的。

【问题讨论】:

  • 你已经把这个复杂化了,但即便如此,在单独的 div 中获取单独的表以具有匹配的列宽总是令人头疼。如果您想要表格中的可滚动部分,为什么不只使用一个表格,并使其 tbody 滚动 - 正如您在帖子中用自己的话所说的那样? medium.com/@vembarrajan/… 给出了一个很好的简单示例,带有演示。你只需要添加一点额外的东西来处理页脚。
  • P.S.我刚刚用谷歌搜索了“html 可滚动表格正文”来找到这个...一个简单的搜索可以为您节省数小时的挫败感 - 对于您能想到的任何 HTML 问题,您很少是第一个遇到它的人 :-)

标签: javascript jquery html css html-table


【解决方案1】:

看来 CSS 确实把你的桌子弄乱了。 尽量不要使用固定宽度(80px),改用 % 宽度。

【讨论】:

  • 我试过了,但还是有一些问题,你能帮我写一些代码吗?
  • 请先删除css中的固定宽度,看看效果如何。是不是看起来已经好一点了?
  • 删除所有宽度后,它采用默认宽度,但我想给特定列一些宽度,但它仍然没有正确对齐