Заказать проект
Оставьте заявку для получения коммерческого предложения.
Заполните форму и мы вышлем Вам предложение в котором решим,
чем можем вам помочь.
Кодим превью загрузки изображений

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

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. Мы будем рады выслушать предложения или, возможно, замечания к вышесказанному. А если все понравилось — сделайте репост;)

Need help?

Ask a question.

Chat Now
Записаться На Консультацию
Записаться На Консультацию
Мы свяжемся
с вами
в течении
10 минут
laptop
Мы свяжемся с вами в течении 10 минут