[Из песочницы] Пишем самый простой и быстрый input type file
Рабочий пример того, что получится:
Сам принцип кастомизированного input file особых отличий не имеет: убираем с экрана input, и всё возлагаем на плечи label, которому мы добавим свои стили. Главное отличие — малое кол-во кода.
Начнём
Мы имеем input и label
Теперь уберём с экрана input, добавив классу my следующие стили:
.my {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
А также стилизуем сам label, добавив ему свои стили:
.label {
width: 180px;
height: 50px;
border-radius: 4px;
text-align: center;
cursor: pointer;
display: block;
font: 14px/50px Tahoma;
transition: all 0.18s ease-in-out;
border: 1px solid #333;
color: #333;
}
.label:hover {
color: white;
background: #333;
}
И теперь самое интересное: javascript. Собственно вот он:
$('.my').change(function() {
if ($(this).val() != '') $(this).prev().text('Выбрано файлов: ' + $(this)[0].files.length);
else $(this).prev().text('Выберите файлы');
});
Он работает следующим образом: Когда пользователь жмёт на input с классом .my, то js начинает отслеживать его изменение. Дальше в дело вступает if (если). Так вот если у нас этот (this) input не пустой (то есть файл был какой-то выбран), то стоящий по соседству выше элемент (это у нас label) получит текст «Выбрано файлов» + кол-во файлов, которое выбрал пользователь. Ну, а если пользователь ничего не выбрал, то label просто получит текст «Выберите файлы».
Всё!
// Дополнительная информация
Может возникнуть проблема с вёрсткой, какая была и у меня. А проблема может заключаться с этим пресловутым .prev (). По факту, есть вероятность того, что невозможно расположить label и input file рядом друг с другом, и текст «Выбрано файлов» будет применяется не к label, а к левому элементу.
Эту проблему можно решить вот так:
Поместите label и input в один div, и дайте этому div’у класс, к примеру «box-form»
Текст какой-то
И замените в js
$(this).prev()
на
$(this).closest('.box-form').children('.label')
Вуаля! Теперь, стоявшие далеко друг от друга, label и input способны взаимодействовать друг с другом.
Лучше, конечно, избегать таких случаев, но никто не защищён от фреймворков, где input’ы пишешь не ты, а их генерирует сам фреймворк…
Спасибо за внимание
Комментарии (5)
6 февраля 2017 в 13:56
+3↑
↓
А разве зависимость в виде JQuery уже считается минималистичным решением?6 февраля 2017 в 14:16
0↑
↓
Конечно же. В хабах же jQuery, а не Javascript. Для настоящих jQuery-программистов.
6 февраля 2017 в 14:39
0↑
↓
Любой пост, начинающийся с «Пишем самый простой\крутой\быстрый %имяФичи%…» содержит в себе jQuery. И лучше не спрашивать: «А с какой целью вы здесь используете jQuery?»6 февраля 2017 в 14:55
+2↑
↓
Моя любимая часть —$(this)[0]
.
6 февраля 2017 в 15:01
0↑
↓
Если
label
не содержит в себеinput
, то он и не будет работать как лейбл. То есть, нужен id у инпута и for у этого лейбла. И если верстка не совсем кривая, то найти нужный лейбл можно через$('label[for=" + this.id + '"]')
.