如何为动态新增表格行的元素生成唯一ID并切换类名
问题解决:动态表格行的图片上传预览功能失效
问题根源
所有动态生成的行里,file输入框、预览容器都使用了重复的ID(upload-file、thumbnail),且仅为第一行的输入框绑定了change事件,导致新增行的上传功能无法触发;同时隐藏/显示上传按钮时使用全局选择器,会影响所有行的元素。
修复方案
- 生成唯一ID:为每行的
file输入框、预览容器、label的for属性添加行索引后缀,确保ID唯一 - 事件委托绑定:使用jQuery的事件委托,监听所有动态生成的
file输入框的change事件 - 上下文元素操作:在处理预览、隐藏/显示上传按钮时,基于当前触发事件的元素所在行进行操作,避免全局影响
修改后的完整代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <button class="btn" type="button" id="add_row2">Add row</button> <button class="btn" type="button" id="delete_row2">Delete row</button> <table class="table" id="tab_logicQual"> <thead> <tr VALIGN=MIDDLE ALIGN=CENTER> <th>#</th> <th>Image</th> <th>Name</th> <th>Type</th> </tr> </thead> <tbody> <tr id='addrQual0' class="fieldGroup"> <td>1</td> <td> <div class="image-upload"> <label for="upload-file-0"><img class='attach-doc' src='https://static.vecteezy.com/system/resources/thumbnails/015/337/675/small/transparent-upload-icon-free-png.png' style='height: 48px'></label> <input id="upload-file-0" type="file" name='img[]' /> </div> <div id="thumbnail-0"></div> </td> <td><input class="form-control" type="text" name='name[]'></td> <td><input class="form-control" type="text" name='type[]'></td> </tr> <tr id='addrQual1'></tr> </tbody> </table>
CSS
.image-upload>input { display: none; } .attach-doc { cursor: pointer; } .img-preview { height: 75px; border: 1px solid #000; margin: 10px 5px 0 0; float: left; } .closeDiv { position: absolute; cursor: pointer; text-align: center; color: #fff; height: 20px; width: 20px; border-radius: 50px; background: rgba(255, 0, 0, 1); margin: 2px -10px; } .pDiv { float: left; position: relative; /* 添加相对定位,让关闭按钮定位正确 */ }
JavaScript
$(document).ready(function() { var i = 1; $("#add_row2").click(function() { // 为当前行生成唯一ID后缀 const rowId = i; $('#addrQual' + i).html(`<td>${i + 1}</td><td><div class='image-upload'><label for='upload-file-${rowId}'><img class='attach-doc' src='https://static.vecteezy.com/system/resources/thumbnails/015/337/675/small/transparent-upload-icon-free-png.png' style='height: 48px'></label><input id='upload-file-${rowId}' type='file' name='img[${rowId}]'/></div><div id='thumbnail-${rowId}'></div></td><td><input class='form-control' type='text' name='name[]'></td><td><input class='form-control' type='text' name='type[]'></td>`); $('#tab_logicQual').append(`<tr id="addrQual${i + 1}"></tr>`); i++; }); $("#delete_row2").click(function() { if (i > 1) { $("#addrQual" + (i - 1)).html(''); i--; } }); // 事件委托:监听所有file输入框的change事件 $(document).on('change', 'input[type="file"][id^="upload-file-"]', function(e) { const files = this.files; const rowId = $(this).attr('id').split('-')[2]; // 获取行索引 showThumbnail(files, rowId); }); // 关闭预览按钮事件 $(document).on('click', '.closeDiv', function() { const pDiv = $(this).parent(); const thumbnailDiv = pDiv.parent(); const imageUploadDiv = thumbnailDiv.prev('.image-upload'); pDiv.remove(); thumbnailDiv.siblings('input[type="file"]').val(''); imageUploadDiv.show(); }); }); function showThumbnail(files, rowId) { const file = files[0]; const thumbnail = document.getElementById(`thumbnail-${rowId}`); const imageUpload = document.getElementById(`upload-file-${rowId}`).closest('.image-upload'); const pDiv = document.createElement("div"); const image = document.createElement("img"); const closeDiv = document.createElement("div"); pDiv.setAttribute('class', 'pDiv'); thumbnail.appendChild(pDiv); image.setAttribute('class', 'img-preview'); pDiv.appendChild(image); closeDiv.innerHTML = "x"; closeDiv.setAttribute('class', 'closeDiv'); pDiv.appendChild(closeDiv); image.file = file; const reader = new FileReader(); reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(image); reader.readAsDataURL(file); image.onload = function() { imageUpload.style.display = 'none'; } }
内容的提问来源于stack exchange,提问作者YK11
相关产品推荐
相关产品推荐

