You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为动态新增表格行的元素生成唯一ID并切换类名

问题解决:动态表格行的图片上传预览功能失效

问题根源

所有动态生成的行里,file输入框、预览容器都使用了重复的ID(upload-file、thumbnail),且仅为第一行的输入框绑定了change事件,导致新增行的上传功能无法触发;同时隐藏/显示上传按钮时使用全局选择器,会影响所有行的元素。

修复方案

  1. 生成唯一ID:为每行的file输入框、预览容器、label的for属性添加行索引后缀,确保ID唯一
  2. 事件委托绑定:使用jQuery的事件委托,监听所有动态生成的file输入框的change事件
  3. 上下文元素操作:在处理预览、隐藏/显示上传按钮时,基于当前触发事件的元素所在行进行操作,避免全局影响

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 04:40:00