Кодим превью загрузки изображений

12 Сентября 2019

следующая статья
Андрей Котенко

Frontend Developer

Андрей Котенко
Кодим превью загрузки изображений

Мы не будем долго объяснять причины, побудившие к созданию данной статьи. Возможность быстро и удобно оперировать изображениями, которые загружаются на сайт, высоко ценят все заказчики. И для них очень важно знать, как будет выглядеть картинка уже на сайте. Итак, я предлагаю на суд фронтенд-разработчикам кастомный, удобный и быстрый способ для реализации превьюшки загруженного изображения на веб-странице. Для наиболее нетерпеливых — в конце статьи вы найдете свободную ссылки на Codepen с готовым результатом.

Рекомендую приготовить кофе/чай, поскольку занятие начинается. Сначала создаем html разметку:

<div class="wrapper">
  <div class="preview"></div>
  <label class="file">
    <input type="file" name="files[0][]" accept="image/jpeg,image/png,image/gif,application/pdf,image/bmp">
    <span>Добавить изображение</span>
  </label>
</div>

Результат:

htmlRus.jpg

Стилизуем: 

.preview {
  display: flex;
  max-width: 1200px;
}
.file {
  display: inline-block;
  padding: 15px 25px;
  margin: 15px;
  background-color: #333;
  color: #fff;
  cursor: pointer;
}
.uploaded {
  width: 25%;
  height: 250px;
  border-radius: 24px;
  border: 1px dashed #000;
  margin: 0 15px;
  overflow: hidden;
  position: relative;
  z-index: 1;
}
.uploaded img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
input {
  display: none;
}
.remove {
  position: absolute;
  z-index: 2;
  width: 20px;
  height: 20px;
  border-radius: 100%;
  background-color: #000;
  border: none;
  top: 15px;
  right: 15px;
  cursor: pointer;
  outline: none;
}
.remove:before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
  width: 14px;
  height: 2px;
  background-color: #fff;
}
.remove:after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(45deg);
  width: 14px;
  height: 2px;
  background-color: #fff;
}

Результат:

cssRus.png

Переходим к реализации превью файла.

Создаем переменные с нужными нам элементами, прелоудером и кнопкой удаления:

var preloaderFile ='<img class="preloader" src="https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif">';

var removeFile = '<button onclick="delFileFromInput()" class="remove"></button>';

Создаем функцию "readURL" с проверкой на загрузку файла:

function readURL(input) {
    if (input.files && input.files[0]) {
    }
}

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

function readURL(input) {
    if (input.files && input.files[0]) {
        var mass = ["image/jpeg", "image/jpg", "image/png", "image/gif", "application/pdf", "image/bmp"];
        var nt = document.createElement('input');
        nt.setAttribute("type", "file");
        var index = $(input).closest('.wrapper').index();
        nt.setAttribute("name", 'files['+index+'][]');
        if($(input).data('name')){
            nt.setAttribute("name", $(input).attr('name'));
            nt.setAttribute("data-name", true);
        }
        nt.setAttribute("accept", "image/jpeg,image/png,image/gif,application/pdf,image/bmp");
    }
} 

После этого создаем объект "FileReader ()", выбираем метод чтения файла "readAsDataURL» и при его загрузке (reader.onload), создаем обертку нашей превьюшки (uploaded) и изображения (img) с результатом чтения файла (e. target.result).

function readURL(input) {
    if (input.files && input.files[0]) {
        var mass = ["image/jpeg", "image/jpg", "image/png", "image/gif", "application/pdf", "image/bmp"];
        var nt = document.createElement('input');
        nt.setAttribute("type", "file");
        var index = $(input).closest('.wrapper').index();
        nt.setAttribute("name", 'files['+index+'][]');
        if($(input).data('name')){
            nt.setAttribute("name", $(input).attr('name'));
            nt.setAttribute("data-name", true);
        }
        nt.setAttribute("accept", "image/jpeg,image/png,image/gif,application/pdf,image/bmp");
        var reader = new FileReader();
        reader.onload = function (e) {
            var div = document.createElement('div');
            $(div).addClass('uploaded');
            var img = document.createElement('img');
            var typec = input.files[0].type;
            var size = input.files[0].size;
            $(img).attr('src', e.target.result);
         }
         reader.readAsDataURL(input.files[0]);
    }
}

Остается сделать проверку на правильность файла и генерацию html.

Для этого создаем две функции и несколько проверок:

//  генерация html
function acceptung() {
                $(div).append(preloaderFile);
                $(div).append(img);
                $(div).append(removeFile);
                $(input).closest('.wrapper').find('.preview').append(div);
                $(input).closest('label').prepend(nt);
                $(div).append(input);
                setTimeout(function() {
                  $(div).find('.preloader').remove();
                }, 500)
            }

	// удаление файла при ошибке
            function declinetung() {
                $(input).closest('label').prepend(nt);
                $(input).remove();
            }
	// проверка на тип и размер файла
            if(typec == "application/pdf"){
                if(size > 11000000){
                    declinetung();
                    alert('max size pdf 10Mb');
                }else{
                    $(img).attr('src', 'images/pdff.jpg');
                    acceptung();
                }
            }else if($.inArray(typec, mass) == -1 ){
                declinetung();
            }else if(size > 6100000){
                    declinetung();
                    alert('max size image 6Mb');
            }else{
                acceptung();
            }

Дорабатываем функционал для удаления файла:

function delFileFromInput() {
    $(document).on('click', '.remove', function () {
        $(this).closest('.uploaded').remove();
    });
}

Декларируем нашу функцию "readURL" по изменению инпут:

$(document).on('change', '.file input',function(){  
    readURL(this);
});

Все, наша превьюшка готова))

Результат:

resultRUS.jpg

Полный код JavaScript:

var preloaderFile ='<img class="preloader" src="https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif">';
var removeFile = '<button onclick="delFileFromInput()" class="remove"></button>';
function readURL(input) {
    if (input.files && input.files[0]) {
        var mass = ["image/jpeg", "image/jpg", "image/png", "image/gif", "application/pdf", "image/bmp"];
        var nt = document.createElement('input');
        nt.setAttribute("type", "file");
        var index = $(input).closest('.wrapper').index();
        nt.setAttribute("name", 'files['+index+'][]');
        if($(input).data('name')){
            nt.setAttribute("name", $(input).attr('name'));
            nt.setAttribute("data-name", true);
        }
        nt.setAttribute("accept", "image/jpeg,image/png,image/gif,application/pdf,image/bmp");
        var reader = new FileReader();
        reader.onload = function (e) {
            var div = document.createElement('div');
            $(div).addClass('uploaded');
            var img = document.createElement('img');
            var typec = input.files[0].type;
            var size = input.files[0].size;
            $(img).attr('src', e.target.result);
            function acceptung() {
                $(div).append(preloaderFile);
                $(div).append(img);
                $(div).append(removeFile);
                $(input).closest('.wrapper').find('.preview').append(div);
                $(input).closest('label').prepend(nt);
                $(div).append(input);
                setTimeout(function() {
                  $(div).find('.preloader').remove();
                }, 500)
                
            }
            function declinetung() {
                $(input).closest('label').prepend(nt);
                $(input).remove();
            }
            if(typec == "application/pdf"){
                if(size > 11000000){
                    declinetung();
                    alert('max size pdf 10Mb');
                }else{
                    $(img).attr('src', 'images/pdff.jpg');
                    acceptung();
                }
            }else if($.inArray(typec, mass) == -1 ){
                declinetung();
            }else if(size > 6100000){
                    declinetung();
                    alert('max size image 6Mb');
            }else{
                acceptung();
            }
        }
        reader.readAsDataURL(input.files[0]);

    }
}
function delFileFromInput() {
    $(document).on('click', '.remove', function () {
        $(this).closest('.uploaded').remove();
    });
}

$(document).on('change', '.file input',function(){  
    readURL(this);
}); 

Как и обещали: результат работы на Codepen: https://codepen.io/approxua/pen/XWraJRE. Мы будем рады выслушать предложения или, возможно, замечания к вышесказанному. А если все понравилось — сделайте репост;)


Похожие статьи

Записаться на консультацию

Мы свяжемся с вами в течении 10 минут