Есть несколько проблем с вашим кодом. Пройдем через них go по одному.
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 spe c: https://html.spec.whatwg.org/multipage/dom.html#the -id-attribute И поскольку существует несколько входов с одинаковым идентификатором, обе метки будут только целевой первый вход. Поэтому мы продолжаем загружать файлы на первый вход, даже когда нажимаем на метку во втором ряду.
Это можно исправить, обернув метку вокруг ввода, чтобы вам не понадобилось для атрибут больше:
<label>
<input />
</label>
2. Вы добавляете только один прослушиватель событий на входе при загрузке страницы Это не ошибка в вашем коде, но это рекомендация, если вы когда-либо добавляете новые элементы на страницу с javascript.
$("#imageUpload").change(...)
Вы создаете прослушиватель события изменения на входе, но только один раз при загрузке страницы. Поэтому, если вы когда-нибудь добавите новый tr с теми же элементами по коду (без глубокого клонирования), на входе в новой строке не будет прослушивателя событий. Это работает в вашем примере, потому что вы создаете глубокий клон tr. Но это не сработает для элементов, которые вы загружаете из ответа AJAX и добавляете в документ.
Я бы порекомендовал вам вместо этого установить прослушиватель событий на document и настроить таргетинг на imageUpload. ребенок. Поскольку документ всегда будет присутствовать на веб-странице и всегда будет только один.
Пример кода прослушивателя документов:
$(document).on("change", ".imageUpload", function(e) {
readURL(e.currentTarget);
});
3. В функции readURL вы нацеливаетесь на imagePreview в первой строке
Эта проблема имеет ту же причину, что и первая проблема, но с другим решением. У нас есть несколько изображений с идентификатором imagePreview . Таким образом, селектор $ ('# imagePreview') будет возвращать только imagePreview в первой строке.
Чтобы выбрать imagePreview в правой строке, вы можете пройти dom до элемента в строка с функцией closest () . И вернитесь к imagePeview с помощью функции find () . Пример:
$(input).closest('.avatar-upload').find('.imagePreview')
Информация о ближайший : https://api.jquery.com/closest/
Информация о find : https://api.jquery.com/find/
Полное решение:
Я разобрал ваш пример скрипки с рабочим примером: https://jsfiddle.net/gkthp6qd/