Предпросмотр загружаемого фото в JavaScript

Поле формы input type="file" не даёт представление о том, что собой представляет загружаемый файл. Единственное на что может опираться пользователь, это отображаемое название файла. Поэтому я решил написать простенький JavaScript предпросмотра загружаемой фотографии, о чём и хочу рассказать в своей статье.

Не откладывая в долгий ящик то, что поможет в понимании решения, приведу следующий пример необходимого нам HTML-кода.

<form id="form" action="upload.php" method="post" enctype="multipart/form-data">
  <div><img alt="" id="image_preview" src="https://lh6.googleusercontent.com/-L17_eJqIsDI/UzbeiYk96RI/AAAAAAAASP4/SbOqhSuEyU4/s100-no/image-is-not-uploaded.jpg"></div>
  <div><input type="file" id="image" name="image"></div>
  <div>
    <input type="reset" value="Reset">
    <input type="submit" value="Upload...">
  </div>
</form>

Примечательно, что для загрузки файлов на сервер обычно используется метод POST, т.к. файлы отправляются в теле HTTP-запроса, а также отключается кодирование данных, т.е. в качестве значения атрибута enctype указывается multipart/form-data.

Если с этим разобрались, то можно перейти и к изучению остальных элементов. В начале идёт элемент предпросмотра фото (image_preview), представленный тегом IMG, в качестве атрибута src которого указан адрес картинки, которая отображается по умолчанию. Далее идёт поле выбора файла с диска (image). Ну и для полноты картины я добавил кнопки сброса данных формы и их отправки скрипту обработки upload.php.

Наша задача состоит в том, чтобы отследить изменение у поля выбора файла с диска (это событие change) и в случае если оно произошло, изменить элемент предпросмотра.

JavaScript код обработчика, с учётом использования библиотеки jQuery, у меня выглядит следующим образом:

$('#image').change(function() {
  var input = $(this)[0];
  if ( input.files && input.files[0] ) {
    if ( input.files[0].type.match('image.*') ) {
      var reader = new FileReader();
      reader.onload = function(e) { $('#image_preview').attr('src', e.target.result); }
      reader.readAsDataURL(input.files[0]);
    } else console.log('is not image mime type');
  } else console.log('not isset files data or files API not supordet');
});

Разберёмся с приведённым примером немного подробней. И так, мы имеем обработчик события change() для элемента с id="image". Далее идёт проверка поддержки API для работы с файлами и наличие файловых данных. Т.к. мы создаём предпросмотр фото, то будет не лишним проверить MIME-тип данных на их соответствие понятию о картинке, т.е. image/jpegimage/png и т.д. Это конечно, не панацея, но тем не менее. Далее я использую FileReader() для чтения данных из файла и сохранения их в JavaScript переменную. Когда данные будут загружены (событие onload), мы присвоим их атрибуту src элемента предпросмотра. Примечательно, что используя readAsDataURL() мы получаем данные в виде схемы data:URL.

И ещё один не лишний момент. Данные формы могут быть сброшены кнопкой reset. В этом случае будет не лишним вернуть нашему элементу предпросмотра фото картинку по умолчанию. Для этого достаточно создать простенький обработчик этого события. У меня он выглядит следующим образом:

$('#form').bind('reset', function() {
  $('#image_preview').attr('src', 'https://lh6.googleusercontent.com/-L17_eJqIsDI/UzbeiYk96RI/AAAAAAAASP4/SbOqhSuEyU4/s100-no/image-is-not-uploaded.jpg');
});

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

На этом у меня всё. Спасибо за внимание. Удачи!

Предприимчивый вебмастер
Предприимчивый вебмастер комментирует...

Вот здесь разделены разметка и JS код.
Протестил, у меня всё заработало.
Давно хотел узнать как работает предпросмотр загружаемых картинок, но всё повода не было. А тут на блюдечке преподнесли :-).
Почему-то раньше думал, что предпросмотр как-то сложнее организовать, как минимум без flash не обойтись, а оказалось, что можно только средствами jquery реализовать.

Константин Кирилюк
Константин Кирилюк комментирует...

2Предприимчивый вебмастер на самом деле вариантов данного решения действительно много. Можно и на Flash, можно и без jQuery, на, так сказать, чистом JavaScript... было бы желание.

Alexander Kushnir
Alexander Kushnir комментирует...

Спасибо огромное! Просто, лаконично, доступно. Реализовал для MODX + Formit работает отлично.