Как сделать отображение определенной иконки для определенного файла в предварительном просмотре загруаемых файлов
У меня есть код, с помощью которого, я могу предварительно просмотреть несколько загруженных файлов:
let file_array = [];
function scrollBottom() {
let element = document.querySelector('.chat-item-body');
element.scrollTop = element.scrollHeight - element.clientHeight;
}
scrollBottom();
$("#chat-file").change(function() {
let input_files = document.getElementById('chat-file').files;
$.each(input_files, function(index, value) {
file_array.push(value);
$('.preview__container').append(`
<div class="preview__content">
<div class="img"><img src="/img/fileType.png" alt=""></div>
<p>${value.name}</p>
<i class="far fa-times-circle delete_file" data-id="${file_array.length - 1}"></i>
</div>
`);
});
});
$(document.body).on('click', '.delete_file', function() {
let file_id = $(this).data('id');
delete file_array[file_id];
$(this).parent().remove();
});
.preview__container {
width: 100%;
margin-top: 10px;
}
.preview__content {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: relative;
margin: 7px 0px;
max-width: 200px;
}
.preview__content .img {
margin-right: 5px;
}
.preview__content .img img {
max-width: 46px;
max-height: 46px;
}
.delete_file {
position: absolute;
right: 10px;
top: 0;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chat-item-body">
<label class="label-file" for="chat-file">
<i class="icon i-clip"></i>
<input type="file" name="file[]" multiple="" id="chat-file" />
</label>
<div class="preview__container">
</div>
</div>
Я сделал так, чтобы значок отображался для любого загруженного документа. Однако нельзя сделать так, чтобы для определённого документа была определённая иконка:
Как это может быть сделано?
Ответы (1 шт):
Если исходить из простоты, то алгоритм следующий:
- Загружаем необходимые иконки на сайт, предварительно дав им названия соответствующие необходимым расширениям;
- Создаём массив с таким же набором расширений (он будет нужен для атрибута accept, чтобы ограничить выбор заданным набором);
- Получаем расширение из имени файла и подставляем его в атрибуте src.
const aFileExt = ["7z", "avi", "bmp", "dll", "doc", "exe", "gif", "html", "jpg", "ogg", "txt", "zip"];
let file_array = [];
function scrollBottom() {
let element = document.querySelector('.chat-item-body');
element.scrollTop = element.scrollHeight - element.clientHeight;
}
scrollBottom();
$('#chat-file')
.change(function() {
let input_files = document.getElementById('chat-file').files;
$.each(input_files, function(index, value) {
file_array.push(value);
let aProp = value.name.split(/\.([^.]+?)$/gim);
$('.preview__container')
.append(
`
<div class="preview__content">
<div class="img">
<img src="https://icons.iconarchive.com/icons/pelfusion/flat-file-type/128/${aProp[1]}-icon.png" alt="">
</div>
<p>${aProp[0]}</p>
<i class="far fa-times-circle delete_file" data-id="${file_array.length - 1}"></i>
</div>
`
);
});
})
.attr('accept', `.${aFileExt.join(',.')}`);
$(document.body).on('click', '.delete_file', function() {
let file_id = $(this).data('id');
delete file_array[file_id];
$(this).parent().remove();
});
.preview__container {
width: 100%;
margin-top: 10px;
}
.preview__content {
display: flex;
align-items: center;
position: relative;
margin: 7px 0px;
max-width: 200px;
}
.preview__content .img {
margin-right: 5px;
}
.preview__content .img img {
max-width: 46px;
max-height: 46px;
}
.delete_file {
position: absolute;
right: 10px;
top: 0;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chat-item-body">
<label class="label-file" for="chat-file">
<i class="icon i-clip"></i>
<input type="file" name="file[]" multiple="" id="chat-file" />
</label>
<div class="preview__container">
</div>
</div>
Можно сделать немного по-другому:
- Подтягиваем изображение со спрайтами (линейное или матрицу) и, на основе размеров, вычисляем позиции иконок;
- Создаём объект, где: ключи - это доступные расширения файлов, а значения - позиция иконки;
- Вычленяем расширение из имени файла и передаём его функции, которая возвращает смещение
background-position, исходя из позиции иконки.
const aFileIcon = {htm: 24, html: 24, css: 23, jpg: 0, txt: 5, wav: 11, mp3: 12, zip: 14, avi: 15};
function fFileIcon(sExt) {
return `${2 - (aFileIcon[sExt] % 5) * 82}px ${2 - Math.floor(aFileIcon[sExt] / 5) * 81}px`;
}
let file_array = [];
function scrollBottom() {
let element = document.querySelector('.chat-item-body');
element.scrollTop = element.scrollHeight - element.clientHeight;
}
scrollBottom();
$('#chat-file')
.change(function() {
let input_files = document.getElementById('chat-file').files;
$.each(input_files, function(index, value) {
file_array.push(value);
let aProp = value.name.split(/\.([^.]+?)$/gim);
$('.preview__container')
.append(
`
<div class="preview__content">
<div class="img"></div><p>${aProp[0]}</p>
<i class="far fa-times-circle delete_file" data-id="${file_array.length - 1}"></i>
</div>
`
)
.find('.preview__content:last-child .img')
.css('background-position', `${fFileIcon(aProp[1])}`);
});
})
.attr('accept', `.${Object.keys(aFileIcon).join(',.')}`);
$(document.body).on('click', '.delete_file', function() {
let file_id = $(this).data('id');
delete file_array[file_id];
$(this).parent().remove();
});
.preview__container {
width: 100%;
margin-top: 10px;
}
.preview__content {
display: flex;
align-items: center;
position: relative;
margin: 7px 0px;
max-width: 200px;
}
.preview__content .img {
margin-right: 5px;
min-width: 80px;
height: 80px;
overflow: hidden;
background-image: url(https://i.stack.imgur.com/TsgGF.jpg);
background-size: 400px 400px;
background-position: 0 0;
}
.delete_file {
position: absolute;
right: 10px;
top: 0;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chat-item-body">
<label class="label-file" for="chat-file">
<i class="icon i-clip"></i>
<input type="file" name="file[]" multiple="" id="chat-file" />
</label>
<div class="preview__container">
</div>
</div>
Необходимые расширения можно добавлять, следя за наличием необходимого изображения. Одновременно ключи (значения) в объекте (массиве) являются набором доступных для выбора расширений - если ключ в объекте отсутствует, то такие файлы просто не отобразятся в окне выбора, исключая ситуацию, когда ассоциированная иконка отсутствует.
Конечно, нужны более серьёзные проверки на стороне сервера, но это уже другой вопрос.
