jQuery按表格行数追加div元素出现重复内容如何解决
问题描述
我尝试读取表格的行数,以总行数减去前4行的结果为数量,创建内嵌对应数据的div元素。但每次运行时,前2个元素渲染正常后会额外生成2个错误div,第3个元素正常后会额外生成3个错误div,错误元素数量随序号递增。

问题代码
JavaScript 逻辑代码
var bestellformular; $.ajax({ type: "GET", url: "https://rsabaugmbh.de/wp-content/uploads/bestellformular.csv", bestellformularType: "text", success: function(response) { bestellformular = $.csv.toArrays(response); generateHtmlTable(bestellformular); } }); // 从CSV生成HTML表格 function generateHtmlTable(bestellformular) { var html = '<table id="produkttabelle" class="produkttabelle">'; if (typeof(bestellformular[0]) === 'undefined') { return null; } else { $.each(bestellformular, function(index, row) { html += '<tr>'; $.each(row, function(index, colbestellformular) { html += '<td>'; html += colbestellformular; html += '</td>'; }); html += '</tr>'; }); html += '</tbody>'; html += '</table>'; alert(html); $('#csv-changes').append(html); }; // 从CSV数据生成商品div var product = '<div class="main_info_inner">'; var rowCount = $('#produkttabelle tr').length - 4; alert(rowCount); if (typeof(bestellformular[0]) === 'undefined') { return null; } else { $.each(bestellformular, function(index, tr) { product += '<div class="product_image product_element"><img src="img/image_missing_error.png" alt=""/></div>'; product += '<div class="product_title product_element"><p>HLP Asian Saladbowl m.Thai-Fal</p><p class="summe_alt">Summe Alt: 20</p><p class="summe_neu">Summe Neu: 18</p></div>'; product += '<div class="add_product"><img src="img/add_row.png" alt=""/></div></div>'; $('#main_info').append(product); }); }; } $(document).ready(function() { $("#lieferdatum").datepicker({ minDate: 0, dateFormat: "dd.mm.yy" }); $("#lieferdatum").datepicker("option", "dateFormat", "dd.mm.yy"); $("#lieferdatum").datepicker("option", "minDate", 0); // 绑定配送日期、机器数量逻辑 $("#create_table").click(function() { var lieferdatum = $('#lieferdatum').val(); var maschinen = $('#maschinen').val() - 1; // 写入配送日期到表格 $('#produkttabelle').find('tr:eq(1)').find('td:eq(2)').html(lieferdatum); }); });
CSS 样式代码
html { height: 100%; min-height: 100% !important; font-family: arial; background: #f1f1f1; } #csv-changes table { display: inline-block; margin: 0 auto; } #csv-changes tr, td { border: 1px solid black; } #csv-changes table tr td { height: 30px; } #csv-changes table tr:nth-child(odd) { background: #e8e8e8; } .container { margin: 0 auto; text-align: center; } #create_table { display: inline-block; margin: 30px; padding: 20px 15px; background: #f7f7f7; border-radius: 20px; text-align: center; } #create_table:hover { cursor: pointer; opacity: 0.7; } .main_info { background: white; max-width: 1450px; margin: 0 auto; padding-bottom: 50px; } .datum { max-width: 250px; display: block; margin: 0 auto; text-align: center; } .main_info_inner { display: flex; align-items: center; justify-content: space-around; max-width: 1360px; width: 100%; padding: 30px 20px; margin: 50px auto; border-radius: 30px; border: 2px solid #dddddd; transition: all 0.4s ease; } .main_info_inner:hover { background: #dddddd; } .main_info_inner.added { background: #F3FFEE; border-color: #1FC243; } .product_element { display: inline-block; vertical-align: middle; } .product_table { background: white; max-width: 70%; overflow: scroll; } .product_table table tbody tr { text-align: center; } .product_table table tbody tr:first-child { background: #97d9ff; } .product_table table tbody tr:nth-child(even):not(:first-child) { background: #ffe097; } .product_image, .product_title { margin-right: 30px; } .summe_alt { margin-bottom: 0; } .summe_neu { margin-top: 0; } .add_product img { max-width: 50px; margin-left: 20px; } .add_product img:hover { opacity: 0.7; cursor: pointer; }
HTML 页面代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/1.0.21/jquery.csv.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!DOCTYPE html> <html> <header> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="robots" content="NONE,NOARCHIVE" /> <link rel="stylesheet" href="css/style.css" type="text/css" media="all" /> <link rel="stylesheet" href="css/date-picker.css" type="text/css" media="all" /> <script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script> <title>Bestellungen</title> </header> <body> <div id="main_info" class="main_info"> <form class="datum"> <label for="lieferdatum">Lieferdatum (DD.MM.YYYY):</label><br> <input type="text" id="lieferdatum" name="lieferdatum"><br> <div id="create_table">Produkte erzeugen</div> </form> </div> <div id="main_info_inner" class="main_info_inner"></div> <div class="container" id="csv-changes"> </div> <script> $(function() { $("#lieferdatum").datepicker(); }); </script> <script src="js/script1.0.js"></script> </body> </html>
问题原因
直接导致div重复生成、错误数递增的核心问题有3个:
- 变量作用域错误:存储商品HTML字符串的
product变量定义在了$.each循环外部,每次循环都会在已有字符串基础上追加新商品内容,而非生成单个商品的HTML。第一次循环拼接1个商品插入页面,第二次循环在原有1个商品的字符串后再拼1个,变成包含2个商品的字符串插入页面,第三次循环变成包含3个商品的字符串插入,最终插入的商品总数为1+2+3+...+n,和描述的错误现象完全吻合。 - 跳过表头逻辑未生效:代码计算了
rowCount = 总行数-4,但遍历CSV数据时没有做索引判断跳过前4行表头,直接遍历了所有行,多生成了表头对应的无效商品div。 - HTML结构语法错误:生成表格时只写了
</tbody>闭合标签,没有写<tbody>开始标签,属于无效HTML结构,会导致DOM查询表格行数时结果异常。
额外笔误:AJAX请求里的bestellformularType: "text"写法错误,应该为dataType: "text",否则jQuery无法正确识别返回内容类型,可能导致CSV解析失败。
修复方案
- 把
product变量的初始化移到$.each循环内部,每次循环生成都重置为单个商品的HTML字符串,避免内容累加。 - 遍历CSV生成商品时,判断索引小于4的行(表头行)直接跳过,只处理有效商品行,不需要额外计算rowCount。
- 补全表格的
<tbody>标签,生成合法的HTML结构,修正AJAX的dataType笔误。 - 后续开发时把写死的商品名称、数值替换成从当前遍历行
tr中读取的实际CSV数据即可。
修复后的核心代码参考:
$.ajax({ type: "GET", url: "https://rsabaugmbh.de/wp-content/uploads/bestellformular.csv", dataType: "text", // 修正笔误 success: function(response) { bestellformular = $.csv.toArrays(response); generateHtmlTable(bestellformular); } }); function generateHtmlTable(bestellformular) { // 补全tbody开始标签 var html = '<table id="produkttabelle" class="produkttabelle"><tbody>'; if (!Array.isArray(bestellformular) || !bestellformular.length) return null; $.each(bestellformular, function(index, row) { html += '<tr>'; $.each(row, function(index, colbestellformular) { html += `<td>${colbestellformular}</td>`; }); html += '</tr>'; }); html += '</tbody></table>'; $('#csv-changes').append(html); // 生成商品 $.each(bestellformular, function(index, tr) { if (index < 4) return; // 跳过前4行表头 // 每次循环内部初始化product,避免累加 let product = '<div class="main_info_inner">'; product += '<div class="product_image product_element"><img src="img/image_missing_error.png" alt=""/></div>'; // 后续替换为tr中读取的实际商品数据 product += '<div class="product_title product_element"><p>HLP Asian Saladbowl m.Thai-Fal</p><p class="summe_alt">Summe Alt: 20</p><p class="summe_neu">Summe Neu: 18</p></div>'; product += '<div class="add_product"><img src="img/add_row.png" alt=""/></div></div>'; $('#main_info').append(product); }); }
更新记录(2022年6月26日)
待实现功能清单:
- 读取CSV表格数据并生成HTML表格
- 用户在页面顶部输入配送日期,该日期值将被追加到已生成的HTML表格对应位置
- 基于CSV内容创建div元素,元素包含商品图片、商品名称、库位编号信息
- 生成的div元素支持选中操作,可通过“+”按钮选择对应商品
- 选中的商品将被添加到HTML表格中
- 用户选择完所有需要的商品后,可将HTML表格导出为CSV文件,同时在服务器端保存一份文件,CSV文件命名规则为"bestellformular"+用户输入的配送日期值
内容的提问来源于stack exchange,提问作者GAX
相关产品推荐
相关产品推荐

