Загрузчик нескольких изображений с предварительным просмотром

Я создал загрузчик изображений, но он не работает должным образом. Я не могу понять, где я иду не так. JSFIDDLE моего загрузчика изображений приведен ниже:

JSFIDDLE

Проблема, с которой я сталкиваюсь, заключается в том, что когда я нажимаю «Выбрать файлы», выбираю более одного файла и открываю его, я хотел, чтобы он показывал предварительный просмотр всех изображений, которые я выбрал, и он работает правильно, но когда я нажимаю кнопку «Удалить», он только удаляет предварительный просмотр означает, что если я отправлю файлы, будут загружены даже те файлы, которые я удалил. С другой стороны, мне нужно нажать кнопку «Добавить больше изображений», чтобы создать еще один загрузчик, как указано выше, но когда я добавляю несколько изображений, он не показывает предварительный просмотр, поэтому я даже не могу выбрать или удалить изображения, которые я выбрал по ошибке. Может ли кто-нибудь найти, где я ошибаюсь. Мне также нужна эта кнопка «Добавить больше изображений», чтобы, если мы забыли добавить некоторые изображения или изображения находятся в другом каталоге, мы могли вызвать еще один файл типа ввода, и он должен работать так же, как и предыдущий.


person Hardik Sisodia    schedule 11.05.2015    source источник


Ответы (2)


Итак, вы делали какие-то странные вещи (например, использовали глобальную переменную с назначенным ей целым числом, которое, как я предполагаю, вы использовали для отслеживания своих объектов).

Я почистил то, что у вас было, и удалил некоторые лишние функции. По сути, вам нужно было лучше использовать функцию JavaScript FileReader(). . Вам нужно будет поближе взглянуть на свои кнопки; так как я не исправить их для вас. ;)

Что вам нужно было сделать, так это перебрать массив this.files и отобразить результаты с помощью функции FileReader(). Код ниже.

    $('#add_more').click(function() {
      "use strict";
      $(this).before($("<div/>", {
        id: 'filediv'
      }).fadeIn('slow').append(
        $("<input/>", {
          name: 'file[]',
          type: 'file',
          id: 'file',
          multiple: 'multiple',
          accept: 'image/*'
        })
      ));
    });

    $('#upload').click(function(e) {
      "use strict";
      e.preventDefault();

      if (window.filesToUpload.length === 0 || typeof window.filesToUpload === "undefined") {
        alert("No files are selected.");
        return false;
      }

      // Now, upload the files below...
      // https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Handling_the_upload_process_for_a_file.2C_asynchronously
    });

    function deletePreview(ele, i) {
      "use strict";
      try {
        $(ele).parent().remove();
        window.filesToUpload.splice(i, 1);
      } catch (e) {
        console.log(e.message);
      }
    }

    $("#file").on('change', function() {
      "use strict";

      // create an empty array for the files to reside.
      window.filesToUpload = [];

      if (this.files.length >= 1) {
        $("[id^=previewImg]").remove();
        $.each(this.files, function(i, img) {
          var reader = new FileReader(),
            newElement = $("<div id='previewImg" + i + "' class='abcd'><img /></div>"),
            deleteBtn = $("<span class='delete' onClick='deletePreview(this, " + i + ")'>delete</span>").prependTo(newElement),
            preview = newElement.find("img");

          reader.onloadend = function() {
            preview.attr("src", reader.result);
            preview.attr("alt", img.name);
          };

          try {
            window.filesToUpload.push(document.getElementById("file").files[i]);
          } catch (e) {
            console.log(e.message);
          }

          if (img) {
            reader.readAsDataURL(img);
          } else {
            preview.src = "";
          }

          newElement.appendTo("#filediv");
        });
      }
    });
#formdiv {
  text-align: center;
}
#file {
  color: green;
  padding: 5px;
  border: 1px dashed #123456;
  background-color: #f9ffe5;
}
#img {
  width: 17px;
  border: none;
  height: 17px;
  margin-left: -20px;
  margin-bottom: 191px;
}
.upload {
  width: 100%;
  height: 30px;
}
.abcd {
  text-align: center;
  position: relative;
}
.abcd img {
  height: 200px;
  width: 200px;
  padding: 5px;
  border: 1px solid rgb(232, 222, 189);
}
.delete {
  color: red;
  font-weight: bold;
  position: absolute;
  top: 0;
  cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="formdiv">
  <div id="filediv">
    <input type="file" id="file" name="files[]" multiple="multiple" accept="image/*" title="Select Images To Be Uploaded">
    <br>
  </div>
  <input type="button" id="add_more" class="upload" value="Add More Images" />
  <input type="submit" name="submit" value="Add Product" class="upload" id="upload" title="Add Product To The Inventory">
</div>

person kneeki    schedule 11.05.2015
comment
Это хорошо работает. Но здесь есть еще одна проблема, я также создал кнопку удаления (значок креста), которая была показана на изображении, чтобы мы могли удалить изображение, если оно выбрано по ошибке, но теперь оно там не отображается. - person Hardik Sisodia; 12.05.2015
comment
Это не должно быть ужасно сложно добавить. Видите, как я добавил область newElement = $("<div id='previewImg" + i + "' class='abcd'><img /></div>")? Чуть ниже сделайте то же самое, только создайте значок крестика удаления. Затем привяжите атрибут onClick к идентификатору нового элемента. Попробуйте. Если вы застряли, дайте мне знать. - person kneeki; 12.05.2015
comment
Я попытался сделать именно то, что вы сказали, но затем он перестал показывать предварительный просмотр изображений, которые я выбираю для загрузки, и показывал мне количество загружаемых изображений, и даже кнопка «Добавить больше» перестала работать после того, как я вставил новую переменную для удаления изображения. - person Hardik Sisodia; 13.05.2015
comment
Добавил кнопку удаления в мой исходный ответ. - person kneeki; 13.05.2015
comment
но это удаляет только предварительный просмотр, если вы видите там, даже после удаления изображения счет остается прежним, это означает, что удаляется только предварительный просмотр, но когда я отправляю форму, он тоже загружает удаленное изображение, верно? - person Hardik Sisodia; 16.05.2015
comment
Правильно, это удалит только предварительный просмотр. Насколько мне известно, массив списка файлов доступен только для чтения. Вот другой пост на эту тему. - person kneeki; 16.05.2015
comment
Я видел ссылку, предоставленную вами, но все же не могу понять после того, как мы добавили кнопку удаления, как мы можем удалить файлы из выбранных файлов, я также пробовал различные методы, но пока не смог завершить этот загрузчик изображений. Я также перешел по этой ссылке и увидел Обработка процесса загрузки для файл но я думаю, что это тоже помогает удалить только превью, но не файлы из раздела выбора файла. - person Hardik Sisodia; 18.05.2015
comment
Я обновил свой фрагмент, чтобы включить удаление файлов из массива (window.filesToUpload). По сути, поскольку FileList является массивом только для чтения, вам необходимо создать уникальный массив, для которого у вас есть права на чтение/запись. - person kneeki; 18.05.2015
comment
Я попробовал ваш обновленный фрагмент, но проблема все еще в том же количестве изображений, т.е. изображения не удаляются из пути выбора файлов, а только из предварительного просмотра - person Hardik Sisodia; 22.05.2015
comment
любые обновления для моего загрузчика изображений, я все еще застрял здесь - person Hardik Sisodia; 01.06.2015
comment
Можете ли вы опубликовать фрагмент (jsfiddle?) с вашим прогрессом? Я был бы рад помочь. - person kneeki; 08.06.2015
comment
Это новый обновленный JsFiddle, а затем, когда я даже попытался сделать функцию загрузки изображений для Добавить больше кнопка, она не подходит для предварительного просмотра не знаю, почему? Пожалуйста, взгляните на обновленный фрагмент. Я даже обновляю фрагмент по заданному мной вопросу. - person Hardik Sisodia; 08.06.2015
comment
Насколько я понимаю, элемент input type="file" доступен только для чтения. Если вы хотите иметь пользовательскую версию, самым безопасным и простым способом будет использование такой библиотеки, как BootStrap FileStyle< /а>. Используя FileStyle вместе со сценариями, которые я уже предоставил, вы сможете добиться именно того, что ищете. - person kneeki; 09.06.2015
comment
Пожалуйста, проверьте этот обновленный JS Fiddle. Я добавил скрипт начальной загрузки и добавлен $(":file").filestyle('clear');, как показано в ссылке, предоставленной вами в последнем комментарии, но по-прежнему не очищается изображение или отдельные изображения с помощью кнопки выбора файла, на самом деле он очищает все изображения, но предварительный просмотр все еще доступен. И загрузчик также изменил мой CSS для input type="file", как я могу сделать его таким же, потому что это выглядит красиво, и мы даже можем правильно перетаскивать изображения в нем.. - person Hardik Sisodia; 09.06.2015
comment
Итак, я полностью понимаю, что вы ищете. Тем не менее, я не уверен, как реализовать эту функцию, чтобы дать пользователю возможность редактировать список файлов /перед/ их загрузкой без какого-либо серьезного хакерства из-за ограничений и мер безопасности только для чтения input type='file'. Тем не менее, вот решение, которое, я надеюсь, вам понравится: jsFiddle - person kneeki; 09.06.2015
comment
это идеально, только одна проблема: если я не хочу удалять все изображения вместе и удалять только одно изображение из 5 изображений, т.е. Если я загрузил 5 изображений вместе, но затем я нахожу неправильное изображение, которое я мог вставить по ошибке, и мне нужно удалить его не все, так как я могу это сделать? - person Hardik Sisodia; 09.06.2015
comment
Удаление одного изображения — это единственное, чего в настоящее время не хватает в этом загрузчике изображений, все остальное — блестяще, и я очень рад вашей поддержке. - person Hardik Sisodia; 09.06.2015
comment
Нет проблем, приятель. Если вы когда-нибудь поймете, как удалить одно изображение из FileList, напишите здесь комментарий, чтобы я мог это проверить. - person kneeki; 09.06.2015
comment
Нужно ли нам создавать значок удаления или флажок, добавляемый к изображению предварительного просмотра, чтобы мы могли удалить одно или несколько изображений? Я думаю, флажок будет работать отлично, но мне интересно, можем ли мы связать этот флажок с новой кнопкой очистки, которая очистит только выбранный? - person Hardik Sisodia; 09.06.2015
comment
Прочитайте мои комментарии выше, afaik, вы не можете удалить ни одного элемента. Вы можете удалить только все элементы. - person kneeki; 09.06.2015
comment
Любая подсказка, как мы можем загрузить все 5 имен изображений в базу данных mysql, но все они должны быть загружены в разные столбцы одной и той же таблицы ?? Например, если в таблице уже создано 5 столбцов, а именно: первое_имя_изображения, второе_имя_изображения, третье_имя_изображения, четвертое_имя_изображения, пятое_имя_изображения, и я выбираю 3 изображения из 5 и отправляю их, поэтому имена изображений из текущего загрузчика изображений должны храниться с приоритетом в разные столбцы. Надеюсь, вы поняли мою точку зрения. - person Hardik Sisodia; 11.06.2015
comment
Я не проверял это, но этого должно быть более чем достаточно, чтобы направить вас на правильный путь. pasteBin - person kneeki; 11.06.2015
comment
Эй, я попытался вставить этот загрузчик изображений в эта форма во 2-м столбце строки изображений, где вы можете увидеть старый загрузчик изображений, но из-за начальной загрузки css вся моя страница запуталась, а затем даже предварительный просмотр не отображается как я могу вставить этот загрузчик изображений в форму? Не могли бы вы проверить это, где я ошибаюсь? Это новый JSFIDDLE с новым загрузчиком изображений. Пожалуйста, проверьте, я не знаю, где я ошибаюсь. - person Hardik Sisodia; 14.06.2015
comment
Вы пытались загрузить безопасный небезопасный (http) на защищенную (https) страницу. Я исправил эти проблемы. По какой-то причине предварительный просмотр не работает на скрипке, но он отлично работает, если вы создадите страницу .html и запустите ее. JSFiddle - person kneeki; 15.06.2015
comment
Я попробовал это, но результат все тот же, загрузочный css тоже мешает моему файлу css, и из-за этого веб-дизайн становится очень грязным. Есть ли другой метод использования загрузчика определенного стиля css, который применяется только к загрузчику изображений, а не ко всей странице? - person Hardik Sisodia; 16.06.2015
comment
Вам нужно просмотреть каждый класс, который использует FileStyle, взять только эти стили из файла bootstrap.css и добавить их в свой конкретный файл CSS. - person kneeki; 17.06.2015
comment
Есть ли какой-нибудь простой способ просто выбрать класс, который необходим для загрузки изображений, из bootstrap css, потому что этот bootstrap CSS довольно большой, и удаление только этого конкретного класса из этого CSS - очень длительный процесс, я пробовал, но это приходит с большим беспорядком в конце. - person Hardik Sisodia; 22.06.2015
comment
Перейти в раздел настройки и отключить все, что вам не нужно? Вы должны перепроверить, но я думаю, что все, что вам нужно, это модуль кнопок. - person kneeki; 22.06.2015
comment
Я тоже пытался это сделать, но все же затронуты теги hr и выравнивания. - person Hardik Sisodia; 25.06.2015
comment
Если вы просматриваете файл css (который представляет собой только компоненты кнопки) из начальной загрузки и убедитесь, что там есть только классы .btn, это не должно повлиять ни на что другое. - person kneeki; 26.06.2015
comment
Я тоже пробовал это сейчас, но все еще мой css затрагивается, и не только я даже пытался нажать на кнопку очистки, и эта кнопка тоже выдает какую-то странную ошибку, и я думаю, что она действует как кнопка отправки позже, после того, как я отредактировал css полностью запутался .. Когда я использую ссылку на веб-сайт, предоставленную вами, для настройки начальной загрузки, и после выбора только значений .btn и загрузки я получаю 4 файла. Я пробовал все четыре css, но до сих пор не добился успеха. - person Hardik Sisodia; 03.07.2015
comment
Если возможно, взгляните на этот запрос - person Hardik Sisodia; 27.08.2015

Это мой первый вклад в StackOverflow. Я надеюсь, что это поможет кому-то. Я довольно новичок в веб-разработке. Однако я был бы признателен, если бы кто-нибудь смог превратить код javascript в цикл. Приведенный ниже код позволяет легко загружать несколько изображений на сервер, используя их уникальные name="name";

function showPreviewOne(event){
    if(event.target.files.length > 0){
      let src = URL.createObjectURL(event.target.files[0]);
      let preview = document.getElementById("file-ip-1-preview");
      preview.src = src;
      preview.style.display = "block";
    } 
  }
  function myImgRemoveFunctionOne() {
      document.getElementById("file-ip-1-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
    }
    /* **************************************************************************************** */

    function showPreviewTwo(event){
      if(event.target.files.length > 0){
        let src = URL.createObjectURL(event.target.files[0]);
        let preview = document.getElementById("file-ip-2-preview");
        preview.src = src;
        preview.style.display = "block";
      } 
    }
    function myImgRemoveFunctionTwo() {
        document.getElementById("file-ip-2-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
      }
    /* **************************************************************************************************** */
    function showPreviewThree(event){
      if(event.target.files.length > 0){
        let src = URL.createObjectURL(event.target.files[0]);
        let preview = document.getElementById("file-ip-3-preview");
        preview.src = src;
        preview.style.display = "block";
      } 
    }
    function myImgRemoveFunctionThree() {
        document.getElementById("file-ip-3-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
      }
    /* **************************************************************************************************** */
    function showPreviewFour(event){
      if(event.target.files.length > 0){
        let src = URL.createObjectURL(event.target.files[0]);
        let preview = document.getElementById("file-ip-4-preview");
        preview.src = src;
        preview.style.display = "block";
      } 
    }
    function myImgRemoveFunctionFour() {
        document.getElementById("file-ip-4-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
      }
      /* **************************************************************************************** */
  
      function showPreviewFive(event){
        if(event.target.files.length > 0){
          let src = URL.createObjectURL(event.target.files[0]);
          let preview = document.getElementById("file-ip-5-preview");
          preview.src = src;
          preview.style.display = "block";
        } 
      }
      function myImgRemoveFunctionFive() {
          document.getElementById("file-ip-5-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
        }
      /* **************************************************************************************************** */
      function showPreviewSix(event){
        if(event.target.files.length > 0){
          let src = URL.createObjectURL(event.target.files[0]);
          let preview = document.getElementById("file-ip-6-preview");
          preview.src = src;
          preview.style.display = "block";
        } 
      }
      function myImgRemoveFunctionSix() {
          document.getElementById("file-ip-6-preview").src = "https://i.ibb.co/ZVFsg37/default.png";
        }
      /* **************************************************************************************************** */
  body {
    margin:0px;
    padding:0px;
    background:#f1f1f1;
  }
 .image-upload-one{
    grid-area: img-u-one;
    display: flex;
    justify-content: center;
  }
  .image-upload-two{
    grid-area: img-u-two;
    display: flex;
    justify-content: center;
  }
  .image-upload-three{
    grid-area: img-u-three;
    display: flex;
    justify-content: center;
  }
  .image-upload-four{
    grid-area: img-u-four;
    display: flex;
    justify-content: center;
  }
  .image-upload-five{
    grid-area: img-u-five;
    display: flex;
    justify-content: center;
  }
  .image-upload-six{
    grid-area: img-u-six;
    display: flex;
    justify-content: center;
  }

  .image-upload-container{
    display: grid;
    grid-template-areas: 'img-u-one img-u-two img-u-three img-u-four img-u-five img-u-six';
  }
  .center {
    display:inline;
    margin: 3px;
  }

  .form-input {
    width:100px;
    padding:3px;
    background:#fff;
    border:2px dashed dodgerblue;
  }
  .form-input input {
    display:none;
  }
  .form-input label {
    display:block;
    width:100px;
    height: auto;
    max-height: 100px;
    background:#333;
    border-radius:10px;
    cursor:pointer;
  }
  
  .form-input img {
    width:100px;
    height: 100px;
    margin: 2px;
    opacity: .4;
  }

  .imgRemove{
    position: relative;
    bottom: 114px;
    left: 68%;
    background-color: transparent;
    border: none;
    font-size: 30px;
    outline: none;
  }
  .imgRemove::after{
    content: ' \21BA';
    color: #fff;
    font-weight: 900;
    border-radius: 8px;
    cursor: pointer;
  }

  .small{
    color: firebrick;
    font-size:15px;
  }

  @media only screen and (max-width: 700px){
    .image-upload-container{
      grid-template-areas: 'img-u-one img-u-two img-u-three'
       'img-u-four img-u-five img-u-six';
    }
  }
 <div class="image-upload-container">
      <div class="image-upload-one">
        <div class="center">
          <div class="form-input">
            <label for="file-ip-1">
              <img id="file-ip-1-preview" src="https://i.ibb.co/ZVFsg37/default.png">
              <button type="button" class="imgRemove" onclick="myImgRemoveFunctionOne()"></button>
            </label>
            <input type="file"  name="img_one" id="file-ip-1" accept="image/*" onchange="showPreviewOne(event);">
          </div>
          <small class="small">Use the &#8634; icon to reset the image</small>
        </div>
      </div>
      <!-- ************************************************************************************************************ -->
      <div class="image-upload-two">
        <div class="center">
          <div class="form-input">
            <label for="file-ip-2">
              <img id="file-ip-2-preview" src="https://i.ibb.co/ZVFsg37/default.png">
              <button type="button" class="imgRemove" onclick="myImgRemoveFunctionTwo()"></button>
            </label>
            <input type="file" name="img_two" id="file-ip-2" accept="image/*" onchange="showPreviewTwo(event);">
          </div>
          <small class="small">Use the &#8634; icon to reset the image</small>
        </div>
      </div>

      <!-- ************************************************************************************************************ -->
      <div class="image-upload-three">
        <div class="center">
          <div class="form-input">
            <label for="file-ip-3">
              <img id="file-ip-3-preview" src="https://i.ibb.co/ZVFsg37/default.png">
              <button type="button" class="imgRemove" onclick="myImgRemoveFunctionThree()"></button>
            </label>
            <input type="file" name="img_three" id="file-ip-3" accept="image/*" onchange="showPreviewThree(event);">
          </div>
          <small class="small">Use the &#8634; icon to reset the image</small>
        </div>
      </div>
      <!-- *********************************************************************************************************** -->
        <div class="image-upload-four">
          <div class="center">
            <div class="form-input">
              <label for="file-ip-4">
                <img id="file-ip-4-preview" src="https://i.ibb.co/ZVFsg37/default.png">
                <button type="button" class="imgRemove" onclick="myImgRemoveFunctionFour()"></button>
              </label>
              <input type="file" name="img_four" id="file-ip-4" accept="image/*" onchange="showPreviewFour(event);">
            </div>
            <small class="small">Use the &#8634; icon to reset the image</small>
          </div>
        </div>
        <!-- ************************************************************************************************************ -->
        <div class="image-upload-five">
          <div class="center">
            <div class="form-input">
              <label for="file-ip-5">
                <img id="file-ip-5-preview" src="https://i.ibb.co/ZVFsg37/default.png">
                <button type="button" class="imgRemove" onclick="myImgRemoveFunctionFive()"></button>
              </label>
              <input type="file" name="img_five" id="file-ip-5" accept="image/*" onchange="showPreviewFive(event);">
            </div>
            <small class="small">Use the &#8634; icon to reset the image</small>
          </div>
        </div>
  
        <!-- ************************************************************************************************************ -->
        <div class="image-upload-six">
          <div class="center">
            <div class="form-input">
              <label for="file-ip-6">
                <img id="file-ip-6-preview" src="https://i.ibb.co/ZVFsg37/default.png">
                <button type="button" class="imgRemove" onclick="myImgRemoveFunctionSix()"></button>
              </label>
              <input type="file" name="img_six" id="file-ip-6" accept="image/*" onchange="showPreviewSix(event);">
            </div>
            <small class="small">Use the &#8634; icon to reset the image</small>
          </div>
        </div>

      <!-- ************************************************************************************************************** -->
    </div>
    

person Eric Coetzee    schedule 12.06.2020
comment
Пожалуйста, не задавайте вопрос в ответ на чужой вопрос. Начать новый вопрос. Спасибо. Удачи. - person Hoppo; 12.06.2020