Проблема с клонированием, загрузкой файлов и предварительным просмотром с помощью Jquery

#javascript #jquery

Вопрос:

У меня есть команда создания клона. Параметр id, созданный как клон, выглядит следующим образом (пример: id = «myid_1»), увеличивает его на единицу и делает id = «myid_2». Пока что никаких проблем нет. Таким образом, каждый объект имеет уникальное значение идентификатора, но простая функция загрузки и предварительного просмотра файлов в этих клонах приводит к сбою моей функции.

Я создал простой пример на jsfiddle. https://jsfiddle.net/magecode/mbk9ps2x/12/

Проблема, которую я понимаю здесь, заключается в том, что значение идентификатора загрузки файла в событии onhange должно увеличиваться параллельно с идентификатором предварительного просмотра изображения. Для этого я прибегнул к функции attr и попытался параллельно увеличить идентификатор, но он так и не изменился.

Код, который я хочу сделать в примере. Значение i всегда увеличивается, но не добавляется к клонированному объекту.

 <div class="clonable-block" data-toggle="cloner">
<a href="#" id="addrow" class="btn btn-info btn-block clonable-button-add" style="border-radius: 0px; font-size: 13px;">
  <i class="fa fa-file pr-2"></i>Add Row</a>
  <div class="clonable">
    <br/>
  <br/>
      <img id="upload_1" alt="your image" width="100" height="100" class="clonable-increment-id" />
      <input type="file" id="preview_1"
      onchange="document.getElementById('upload_1').src = window.URL.createObjectURL(this.files[0])">
        <br/>
  <br/>
  </div>
</div> 
        var i = 1;
    $("#addrow").click(function () {
        i  ;

        $("#upload_"   i "").attr("onchange", "document.getElementById('preview_'  i   '').src = window.URL.createObjectURL(this.files[0])");

    });
 

Комментарии:

1. Привет, Мустафа!, я видел твою скрипку. Проблема в том, что при изменении изображения изображение меняется в первой строке, а не в той строке, которую вы хотели изменить. Может быть, проблема не в этом, а просто в том, чтобы уточнить.

2. Здравствуйте, спасибо вам за ваш ценный комментарий. На самом деле я понимаю проблему, но у меня возникли проблемы с тем, как ее решить. Мой идентификатор предварительного просмотра увеличивается, и вместе с ним значение идентификатора в «onchange» также должно увеличиться, но я не смог найти способ его увеличить.

Ответ №1:

Я воссоздал это с помощью vanilla.js, затем вы можете преобразовать его в Jquery. Дело в том, что это могло бы быть намного проще. Я рекомендую вам vanilla.js, у него лучшая общая производительность, но я понимаю простоту Jquery. Вот и все:

 const CloneSource = document.querySelector(".clonable-source");
const buttonRow = document.getElementById("add_row");
const clonesContainer = document.getElementById("clones");
let globalCounter = 1; // Create a globalCounter for the Form IDs

window.addEventListener("change", function(e) {
  let target = e.target
  // This try catch is just for strictly saying that we 
  // want to target the .clonable class
  try {
    let form = target.closest(".clonable")
    let fd = new FormData(form)
    let img = fd.get("img");
    let preview = form.children[0]
    let url = URL.createObjectURL(img)
    preview.setAttribute("src", url);
  } catch {
    console.log("No Form")
  }

})

buttonRow.addEventListener("click", function(e) {
  // Creates Form, img, and input elements
  let formSource = document.getElementById("source")
  let Form = document.createElement("form")
  let Img = document.createElement("img")
  let Input = document.createElement("input")
  Form.className = `clonable clonable-clone`
  Form.setAttribute("id", `clonable-${globalCounter}`) // This add the ID to the Form
  
  globalCounter  ; // Sum 1 to the globalCounter;      

  Img.setAttribute("src", formSource.children[0].getAttribute("src"))

  Input.setAttribute("type", "file")
  Input.setAttribute("name", "img")

  Form.appendChild(Img)
  Form.appendChild(Input)
  // Then append the form to the clones container
  clonesContainer.appendChild(Form);
}); 
 img {
  width: 5rem;
} 
 <button id="add_row">Add Row</button>
<div id="clones">
  <form class="clonable clonable-source" id="source">
    <img src="#">
    <input type="file" name="img">
    <p>Select an Image</p>
  </form>
</div> 

Комментарии:

1. эй, это здорово и работает просто отлично. Однако это не сработало, когда я попытался заставить его работать должным образом с помощью моего текущего метода клонирования. У меня есть такие пункты, как «выбрать», «войти». У меня есть форма, в которой я зарегистрировал их всех с разными идентификаторами, поэтому идентификаторы должны быть разными. Также спасибо вам за совет, я новичок в этом деле и обязательно последую вашему совету после этой работы.

2. Идеально, поэтому вам нужно добавить динамические идентификаторы. Вы можете добавить в прослушиватель событий buttonRow идентификаторы для созданной нами переменной формы и создать счетчик вне функции, который суммирует 1 при каждом нажатии кнопки. Я отредактирую ответ с учетом этого идентификатора.