Виджет для загрузки изображений

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

Когда вы нажимаете input[type=file], ОС позаботится об открытии диалога, в котором обычно можно просматривать локальный диск и видеть эскизы изображений. Собственно, проблема обратной связи возникает после того, как пользователь выбирает один (или более) файл изображения и нажимает кнопку «Открыть»: теперь он видит только имя файла (выбранных файлов), а не содержимое.

Предположим, у вас есть следующая HTML-разметка для вашего элемента управления загрузкой изображения:

<input id="image" type="file" placeholder="Image" />

Его нетрудно стилизовать так:

Image upload (CSS-only) widget

Посмотрите, как это делается (надо только немного поправить код, чтобы получить результат, как на картинке):

See this code Images uploader on x.xhtml.ru.

Нам по-прежнему нужно сделать предварительный просмотр выбранных пользователем изображений. Например использовать HTML5 FileReader API, точнее его метод FileReader.readAsDataURL(), который позволяет получить содержимое выбранного изображения перед его отправкой на сервер (то есть, до того, как пользователь подтвердит отправку формы).

Метод кодирует содержимое изображения в Data URI, а эту закодированную строку браузер спокойно умеет разбирать и рендерить.

Получив содержимое изображения в Data URI, с помощью Javascript добавим предпросмотр картинки элементу управления загрузкой:

function onImageFileSelected (evt) {
  const imageInput = evt.target;
  const images = Array.from(evt.target.files).map(file => file.name);
  // Removes previous preview images.
  imageInput.closest('.field').find('.preview').remove();
  // Generates new preview images.
  $.map(files, function(file) {
    reader.addEventListener("load", function () {
      var url = reader.result;
      var preview = file_input.before('<img class="preview" alt="" src="' + url + '"/>');
    }, false);
    if (file) {
      reader.readAsDataURL(file);
    }
  });
}

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

image upload widget with foto

С помощью CSS можно окончательно настроить эту штуку.