如何更改动态表中的特定图像?

帕特里克·布里奇

我在一张桌子上面临这种奇怪的行为,老实说我不知道​​我在这里错过了什么。

我有下表:

<table>
<tr>
    <th>City</th>
    <th>Date</th>
    <th>Description</th>
    <th>Picture</th>
    <th>Sort</th>
    <th>
        <span class="table-add mb-3 mr-2">
          <a href="#!" class="text-success">
             <i class="fas fa-plus fa-2x program" aria-hidden="true"></i>
          </a>
        </span>
    </th>
</tr>
<tr>
    <td>Name</td>
    <td>01-01-20</td>
    <td>Lorem ipsum dolor sit amet.</td>
    <td>
        <div class="container-image">
            <div class="avatar-upload">
                <div class="avatar-edit">
                    <input type='file' id="imageUpload" accept=".png, .jpg, .jpeg" />
                    <label for="imageUpload"></label>
                </div>
                <div class="avatar-preview">
                    <div id="imagePreview" class="imagePreview" style="background-image: url(http://i.pravatar.cc/);">
                    </div>
                </div>
            </div>
        </div>
    </td>
    <td></td>
</tr>

我有一个图标按钮来克隆我的最后一个“tr”并在我的桌子底部创建一个新的。

我还有一个 jquery 函数可以将图像上传到每一行,但是由于某种原因,例如当我更改第三行中的图像时,它总是会更新我的第一行。

<script>
function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function(e) {
            $('#imagePreview').css('background-image', 'url('+e.target.result +')');
            $(this).hide();
            $(this).fadeIn(650);
        };
        reader.readAsDataURL(input.files[0]);
    }
}
$("#imageUpload").change(function() {
    readURL(this);
});

我创建了一个带有我的表的功能示例的 JSFiddle,以便让您对这个问题有一个确切的了解:https ://jsfiddle.net/d95yo4vg/

只需添加一个新行,然后尝试更改第二行的图像。

黄鼠狼

您的代码有几个问题。让我们一次通过它们。

1.点击图片图标标签没有打开右侧输入标签的上传对话框

添加新行时,您会在 html 中获得这些元素:

<input type='file' id="imageUpload" accept=".png, .jpg, .jpeg" />
<label for="imageUpload"></label>

<input type='file' id="imageUpload" accept=".png, .jpg, .jpeg" />
<label for="imageUpload"></label>

因为我们有多个具有相同值的 id 属性,所以我们违反了 html5 规范:https : //html.spec.whatwg.org/multipage/dom.html#the-id-attribute并且因为有多个具有相同 id 的输入,两个标签都只针对第一个输入。因此,即使我们单击第二行中的标签,我们也会继续将文件上传到第一个输入。

您可以通过在输入周围包裹标签来解决此问题,这样您就不再需要for属性了:

<label>
  <input />
</label>

2. 您只在页面加载时在输入上添加一个事件侦听器这不是您的代码中的错误,但这是一个建议,以防您使用 JavaScript 向页面添加新元素。

$("#imageUpload").change(...)

您正在输入上创建更改事件侦听器,但仅在页面加载时创建一次。因此,如果您通过代码(没有深度克隆)添加具有相同元素的新 tr,则新行中的输入没有事件侦听器。它在您的示例中确实有效,因为您创建了 tr 的深层克隆。但它不适用于您从 AJAX 响应加载并添加到文档的元素。

我建议您在文档上设置一个事件侦听器,并以 imageUpload 子对象为目标。因为该文档将始终存在于网页上,并且始终只有一个。

文档侦听器的代码示例:

$(document).on("change", ".imageUpload", function(e) {
  readURL(e.currentTarget);
});

3. 在 readURL 函数中,您的目标是第一行中的 imagePreview

此问题与第一个问题的原因相同,但有另一种解决方案。我们有多个带有imagePreview id 的img 所以$('#imagePreview')选择器将只返回第一行中的 imagePreview。

要选择右侧行上的 imagePreview,您可以使用最接近的 ()函数将 dom 向上遍历到行中的元素使用find()函数遍历回imagePeview一个例子:

$(input).closest('.avatar-upload').find('.imagePreview')

关于最近的信息https : //api.jquery.com/closest/

关于查找的信息https : //api.jquery.com/find/


完整的解决方案:

我已将您的小提琴示例分叉为一个工作示例:https : //jsfiddle.net/gkthp6qd/

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章