Стилизация ввода type = кнопка «file»


736

Как вы стилизуете type="file"кнопку ввода ?


Я добавлю свой собственный ответ, чтобы сделать это так, как я сделал ... но вот пример, основанный на начальной загрузке, который может помочь .. geniuscarrier.com/…
Вишну Наранг

Ответы:


235

Обработка файловых вводов общеизвестно сложна, так как большинство браузеров не изменят внешний вид ни CSS, ни Javascript.

Даже размер ввода не будет реагировать на подобные:

<input type="file" style="width:200px">

Вместо этого вам нужно будет использовать атрибут размера:

<input type="file" size="60" />

Для любого более сложного стиля (например, изменение внешнего вида кнопки обзора) вам необходимо рассмотреть хитрый подход к наложению стилизованной кнопки и поля ввода поверх ввода исходного файла. Статья, уже упомянутая rm на www.quirksmode.org/dom/inputfile.html, является лучшей, которую я видел.

ОБНОВИТЬ

Несмотря на то, что сложно <input>напрямую оформить тег, это легко сделать с помощью <label>тега. Смотрите ответ ниже от @JoshCrozier: https://stackoverflow.com/a/25825731/10128619


7
Только что нашел решение jquery на основе этого скрипта здесь: blog.vworld.at/2008/08/21/…
mtness

1
@TLK Ответ Райана не будет работать в IE при попытке загрузки iframe. Это дает вам ошибку «Отказано в доступе». Для обычных загрузок я согласен, что это самый простой способ!
морозное чудо

3
Гораздо более простое решение , чем QuirksMode объяснил здесь . Просто разместите эту ссылку здесь, так как этот ответ в любом случае является ответом только на ссылку.
Joeytje50

10
Для тех, кто интересуется современным подходом, я бы посоветовал взглянуть на этот ответ . Он не требует JavaScript, как и некоторые другие ответы.
Джош Крозье

3
@JoshCrozier опубликовал безумно лучшее решение. Даже превосходит фальшивые мышиные решения :)
Lodewijk

1022

Вам не нужен JavaScript для этого! Вот кросс-браузерное решение:

Смотрите этот пример! - Работает в Chrome / FF / IE - (IE10 / 9/8/7)

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

<label for="file-upload" class="custom-file-upload">
    Custom Upload
</label>
<input id="file-upload" type="file"/>

В качестве альтернативы вы можете просто обернуть элемент ввода файла меткой напрямую: (пример)

<label class="custom-file-upload">
    <input type="file"/>
    Custom Upload
</label>

С точки зрения стиля, просто скройте 1 элемент ввода, используя селектор атрибута .

input[type="file"] {
    display: none;
}

Тогда все, что вам нужно сделать, это стилизовать пользовательский labelэлемент. (пример) .

.custom-file-upload {
    border: 1px solid #ccc;
    display: inline-block;
    padding: 6px 12px;
    cursor: pointer;
}

1 - Стоит отметить, что если вы скрываете элемент с помощью display: none, он не будет работать в IE8 и ниже. Также следует учитывать тот факт, что jQuery validate не проверяет скрытые поля по умолчанию. Если любая из этих вещей является проблемой для вас, вот два разных способа скрыть ввод ( 1 , 2 ), который работает в этих обстоятельствах.


43
У меня действительно есть вопрос с этим, хотя, при выборе файла, как бы мы поступили, затем отобразив имя файла?
Ричлвис

17
Как отобразить имя выбранного файла, если display: noneзадано значение input[type=file]?
Сартак Сингхал

38
Отличное решение, но на самом деле вам нужен JavaScript. Если вы хотите отобразить имя файла, как просили другие люди, вам нужно добавить интервал между меткой и скрытым вводом: <span id = "file-selected"> </ span>. Затем обновите диапазон для события изменения: $ ('# file-upload'). Bind ('change', function () {var fileName = ''; fileName = $ (this) .val (); $ ('#) file-selected '). html (fileName);})
Сэм

9
Вы должны использовать position: absolute; left: -99999remвместо того, чтобы display: noneпо причинам доступности. Чаще всего программы чтения с экрана не читают элементы, если они скрыты с использованием display: noneметода.
Капсула

10
Я очень удивлен, обнаружив, что никто, похоже, не задумывался о доступности клавиатуры. labelэлементы не доступны buttonс клавиатуры, в отличие от s и inputs. Добавление tabindexне является решением, потому что оно labelвсе равно не будет действовать, когда оно имеет фокус и пользователь нажимает ввод. Я решил эту проблему, визуально скрыв ввод, чтобы его можно было сфокусировать, а затем применил:focus-within к labelродителю: jsbin.com/fokexoc/2/edit?html,css,output
Оливер Джозеф Эш,

195

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

  1. это простая форма HTML (пожалуйста, прочитайте комментарии HTML, которые я написал здесь ниже)

    <form action="#type your action here" method="POST" enctype="multipart/form-data">
      <div id="yourBtn" style="height: 50px; width: 100px;border: 1px dashed #BBB; cursor:pointer;" onclick="getFile()">Click to upload!</div>
      <!-- this is your file input tag, so i hide it!-->
      <div style='height: 0px;width:0px; overflow:hidden;'><input id="upfile" type="file" value="upload"/></div>
      <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
      <input type="submit" value='submit' >
    </form>
  2. затем используйте этот простой скрипт для передачи события click в тег ввода файла.

    function getFile(){
         document.getElementById("upfile").click();
    }

    Теперь вы можете использовать любой тип стилей, не беспокоясь о том, как изменить стили по умолчанию.

Я знаю это очень хорошо, потому что я пытался изменить стили по умолчанию в течение полутора месяцев. поверьте мне, это очень сложно, потому что разные браузеры имеют разные теги ввода загрузки. Так что используйте этот для создания ваших пользовательских форм загрузки файлов. Вот полный код автоматической загрузки.

function getFile() {
  document.getElementById("upfile").click();
}

function sub(obj) {
  var file = obj.value;
  var fileName = file.split("\\");
  document.getElementById("yourBtn").innerHTML = fileName[fileName.length - 1];
  document.myForm.submit();
  event.preventDefault();
}
#yourBtn {
  position: relative;
  top: 150px;
  font-family: calibri;
  width: 150px;
  padding: 10px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  border: 1px dashed #BBB;
  text-align: center;
  background-color: #DDD;
  cursor: pointer;
}
<form action="#type your action here" method="POST" enctype="multipart/form-data" name="myForm">
  <div id="yourBtn" onclick="getFile()">click to upload a file</div>
  <!-- this is your file input tag, so i hide it!-->
  <!-- i used the onchange event to fire the form submission-->
  <div style='height: 0px;width: 0px; overflow:hidden;'><input id="upfile" type="file" value="upload" onchange="sub(this)" /></div>
  <!-- here you can have file submit button or you can write a simple script to upload the file automatically-->
  <!-- <input type="submit" value='submit' > -->
</form>


6
@ user1053263 -> Спасибо за рекомендацию .. здесь я использовал очень простой java-скрипт, не нужно использовать фреймворки, такие как Jquery или PrototypeJS.
teshguru

7
У меня проблемы с отправкой формы в IE9. Я получаю сообщение об ошибке «Доступ запрещен», который пытается отправить форму через JavaScript. Если я нажимаю кнопку отправки через интерфейс, это работает. Есть ли обходной путь для этого?
Кевин

1
@kevin -> Пожалуйста, попробуйте event.preventDefault () после document.myForm.submit (), я внес изменения в приведенный выше код.
Тешгуру

1
Хорошо работает в Chrome, Firefox, Safari & Opera - но не в IE9. В IE9 я получаю ту же ошибку «Доступ запрещен», что и @Kevin - и иногда просто тихий сбой без ошибок.
daveywc

10
В IE10 (и, возможно, IE9 и т. Д.) Вы получите «Доступ запрещен» (или нет ответа от jQuery), если вы попытаетесь автоматически отправить форму после нажатия кнопки ввода файла через javascript. Таким образом, этот метод работает для стилизации кнопки ввода файла, пока пользователь все еще отправляет форму. Мне потребовалось время, чтобы найти это, и я вижу, что другие тоже имеют такую ​​же проблему. См. Это для получения дополнительной информации stackoverflow.com/a/4335390/21579 .
Джефф Видмер

76

Скройте его с помощью css и используйте пользовательскую кнопку с $ (селектор) .click (), чтобы активировать кнопку обзора. затем установите интервал для проверки значения типа ввода файла. интервал может отображать значение для пользователя, чтобы пользователь мог видеть, что загружается. интервал будет очищаться при отправке формы [ПРАВИТЬ] Извините, я был очень занят, намеревался обновить этот пост, вот пример

<form action="uploadScript.php" method="post" enctype="multipart/form-data">
<div>
    <!-- filename to display to the user -->
    <p id="file-name" class="margin-10 bold-10"></p>

    <!-- Hide this from the users view with css display:none; -->
    <input class="display-none" id="file-type" type="file" size="4" name="file"/>

    <!-- Style this button with type image or css whatever you wish -->
    <input id="browse-click" type="button" class="button" value="Browse for files"/>

    <!-- submit button -->
    <input type="submit" class="button" value="Change"/>
</div>

$(window).load(function () {
    var intervalFunc = function () {
        $('#file-name').html($('#file-type').val());
    };
    $('#browse-click').on('click', function () { // use .live() for older versions of jQuery
        $('#file-type').click();
        setInterval(intervalFunc, 1);
        return false;
    });
});

7
Обратите внимание, что если вы используете этот способ, он сломается в Internet Explorer, потому что это исключение безопасности ..
Rejinderi

1
спасибо совет. Когда я использую IE, он обычно имеет отдельный макет для всего остального. Ненавижу IE. но я упрощаю все в IE.
Райан

1
С FF20 $ ('# file-type'). Click (), кажется, не вызывает диалог «Выбор файла» - на самом деле ничего не происходит. Любые идеи?
andig

2
Попробуйте использовать метод триггера в jquery. Также .live изменился на .on () в новом jquery
Райан

1
Как только вы установите этот интервал, в какой момент я могу его очистить? иначе это будет постоянно увольнять
Дейв Хей

60

HTML

<div class="new_Btn">SelectPicture</div><br>
<input id="html_btn" type='file'" /><br>

CSS

.new_Btn {
// your css propterties
}

#html_btn {
 display:none;
}

JQuery

$('.new_Btn').bind("click" , function () {
        $('#html_btn').click();
    });
//edit: 6/20/2014: Be sure to use ".on" not ".bind" for newer versions of jQuery

Скрипка : http://jsfiddle.net/M7BXC/

Вы также можете достичь своих целей без jQuery с обычным JavaScript.

Теперь newBtn связан с html_btn, и вы можете оформить новый btn так, как вам хочется: D


1
Просто любопытно, работает ли он в каждом браузере нового поколения, таком как Firefox, IE, Opera, Safari, Chrome и т. Д.?
Wh1T3h4Ck5

Это самое простое решение для меня! По крайней мере, в IE 9, Chrome 23 и FF 16 с jQuery 1.7.2, поэтому с обновленными версиями он должен работать.
Дани Бишоп

Кто-нибудь знает, как изменить .new_Btn, если пользователь выбрал изображение. Теперь это просто показывает тот же класс. Кто-нибудь знает, как это отследить? Спасибо
Андо

2
@MehdiKaramosly это работает даже в IE 6 - но это верно только для jQuery 1.x , jQuery 2.x + не поддерживает старые IE
jave.web

1
@Ando via Javascript / jQuery => значение входного файла пустое или содержит локальный путь к файлу => использовать событие onchange и проверить на val () :) см. Jsfiddle.net/ZrBPF
jave.web

55

Все движки рендеринга автоматически генерируют кнопку при <input type="file">создании. Исторически эта кнопка была совершенно непригодна для стиля. Тем не менее, Trident и WebKit добавили хуки через псевдоэлементы.

Трезубец

Начиная с IE10, кнопка ввода файла может быть стилизована с использованием ::-ms-browseпсевдоэлемента. По сути, любые правила CSS, которые вы применяете к обычной кнопке, могут быть применены к псевдоэлементу. Например:

::-ms-browse {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Это отображается следующим образом в IE10 в Windows 8:

Это отображается следующим образом в IE10 в Windows 8:

WebKit

WebKit предоставляет хук для своей кнопки ввода файла с ::-webkit-file-upload-buttonпсевдоэлементом. Опять же, почти любое правило CSS может быть применено, поэтому пример Trident будет работать и здесь:

::-webkit-file-upload-button {
  background: black;
  color: red;
  padding: 1em;
}
<input type="file">

Это отображается следующим образом в Chrome 26 на OS X:

Это отображается следующим образом в Chrome 26 на OS X:


Для таких программ, основанных на Gecko, как Firefox, нет особых возможностей по стилю.
Ансельм

2
В ответе, используя css, как скрыть слово «Файл не выбран» в теге <input type = file>. Пожалуйста, прокомментируйте меня.
user2086641

Я понятия не имею, извините
Ансельм

1
источник: tjvantoll.com/2013/04/15/…
Anselm

1
Если кто-то хочет поиграть со стилями, я добавил сюда jsfidde
Питер Дриннан,

26

Если вы используете Bootstrap 3, это работает для меня:

См. Http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/

.btn-file {
  position: relative;
  overflow: hidden;
}
.btn-file input[type=file] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  filter: alpha(opacity=0);
  opacity: 0;
  outline: none;
  background: white;
  cursor: inherit;
  display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />

<span class="btn btn-primary btn-file">
    Browse...<input type="file">
</span>

Который производит следующую кнопку ввода файла:

Пример кнопки

Серьезно, проверьте http://www.abeautifulsite.net/whipping-file-inputs-into-shape-with-bootstrap-3/


2
Это сохраняет функциональность перетаскивания, что замечательно :), большинство ответов не принимают пропущенные файлы.
A1rPun

25

Рабочий пример здесь с собственной поддержкой Drag and drop: https://jsfiddle.net/j40xvkb3/

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

display: noneПодход разрушает нативную поддержку перетаскивания.

Чтобы ничего не нарушать, вы должны использовать opacity: 0подход для ввода и расположить его, используя относительный / абсолютный шаблон в оболочке.

Используя эту технику, вы можете легко стилизовать зону щелчка / отбрасывания для пользователя и добавить собственный класс в javascript для dragenterсобытия, чтобы обновить стили и дать пользователю обратную связь, чтобы он мог видеть, что он может удалить файл.

HTML:

<label for="test">
  <div>Click or drop something here</div>
  <input type="file" id="test">
</label>

CSS:

input[type="file"] {
  position: absolute;
  left: 0;
  opacity: 0;
  top: 0;
  bottom: 0;
  width: 100%;
}

div {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ccc;
  border: 3px dotted #bebebe;
  border-radius: 10px;
}

label {
  display: inline-block;
  position: relative;
  height: 100px;
  width: 400px;
}

Вот рабочий пример (с дополнительным JS для обработки dragoverсобытий и удаленных файлов).

https://jsfiddle.net/j40xvkb3/

Надеюсь, это помогло!


спасибо за пост, как это работает, если добавлен атрибут множественного = "несколько", я перетащил 2 изображения, но видел путь только для 1-го
PirateApp

Вы пропустили код здесь. На скрипке больше. Какая библиотека?
Ctrl-Alt-Delor

На скрипке есть только какой-то javascript с jQuery, чтобы показать файлы, которые были отброшены. Вот и все
кевча

Внедрив это решение и протестировав его, оно, похоже, не работает и в Edge.
ChrisA

1
Ах, хорошо, я пропустил упаковщик с положением родственника в вашем ответе - Мой плохой. Если ввод ниже размеров экрана, браузер пытается прокрутить до него и при этом перемещает контейнер прокрутки вверх по странице. Вот демонстрация: stackblitz.com/edit/input-file-overflow?file=style.css (просто не совсем демонстрирует, как абсолютное положение является причиной поведения)
Том

23

Я могу сделать это с помощью чистого CSS с использованием приведенного ниже кода. Я использовал bootstrap и font-awesome.

<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" />

<label class="btn btn-default btn-sm center-block btn-file">
  <i class="fa fa-upload fa-2x" aria-hidden="true"></i>
  <input type="file" style="display: none;">
</label>


21
 <label>
    <input type="file" />
 </label>

Вы можете обернуть свой ввод type = "file" внутри метки для ввода. Стилизуйте метку так, как вам нравится, и скройте ввод с помощью display: none;


Альтернативой может быть gist.github.com/barneycarroll/5244258 или jsfiddle.net/4cwpLvae (работает в IE11)
surfmuggle

12

Вот решение, которое на самом деле не стилизует <input type="file" />элемент, а вместо этого использует <input type="file" />элемент поверх других элементов (которые можно стилизовать). <input type="file" />Элемент не очень видно , следовательно, общая иллюзия имеет красиво стилизованное управление загрузкой файлов.

Недавно я столкнулся с этой проблемой, и, несмотря на множество ответов о переполнении стека, ни один из них, похоже, не отвечал всем требованиям. В итоге я настроил это так, чтобы получить простое и элегантное решение.

Я также проверил это на Firefox, IE (11, 10 и 9), Chrome и Opera, iPad и некоторых устройствах Android.

Вот ссылка на JSFiddle -> http://jsfiddle.net/umhva747/

$('input[type=file]').change(function(e) {
    $in = $(this);
    $in.next().html($in.val());
    
});

$('.uploadButton').click(function() {
    var fileName = $("#fileUpload").val();
    if (fileName) {
        alert(fileName + " can be uploaded.");
    }
    else {
        alert("Please select a file to upload");
    }
});
body {
    background-color:Black;
}

div.upload {
    background-color:#fff;
    border: 1px solid #ddd;
    border-radius:5px;
    display:inline-block;
    height: 30px;
    padding:3px 40px 3px 3px;
    position:relative;
    width: auto;
}

div.upload:hover {
    opacity:0.95;
}

div.upload input[type="file"] {
    display: input-block;
    width: 100%;
    height: 30px;
    opacity: 0;
    cursor:pointer;
    position:absolute;
    left:0;
}
.uploadButton {
    background-color: #425F9C;
    border: none;
    border-radius: 3px;
    color: #FFF;
    cursor:pointer;
    display: inline-block;
    height: 30px;
    margin-right:15px;
    width: auto;
    padding:0 20px;
    box-sizing: content-box;
}

.fileName {
    font-family: Arial;
    font-size:14px;
}

.upload + .uploadButton {
    height:38px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form action="" method="post" enctype="multipart/form-data">
    <div class="upload">
        <input type="button" class="uploadButton" value="Browse" />
        <input type="file" name="upload" accept="image/*" id="fileUpload" />
        <span class="fileName">Select file..</span>
    </div>
    <input type="button" class="uploadButton" value="Upload File" />
</form>

Надеюсь это поможет!!!


2
Гениально умное решение для этого гнусного мошенничества.
rmcsharry

Лучший из всех. Отлично!!
Карра

11

Это просто с jquery. Дать пример кода предложения Райана с небольшой модификацией.

Основной HTML:

<div id="image_icon"></div>
<div id="filename"></div>
<input id="the_real_file_input" name="foobar" type="file">

Не забудьте установить стили для ввода, когда вы будете готовы: opacity: 0 вы не можете установить, display: noneпотому что он должен быть кликабельным. Но вы можете расположить его под «новой» кнопкой или заправить под что-то еще с помощью z-index, если хотите.

Установите некоторые jquery, чтобы щелкнуть по реальному вводу, когда вы щелкнете по изображению.

$('#image_icon').click(function() {
    $('#the_real_file_input').click();
});

Теперь ваша кнопка работает. Просто измените и вставьте значение при изменении.

$('input[type=file]').bind('change', function() {
    var str = "";
    str = $(this).val();
    $("#filename").text(str);
}).change();

Тах да! Возможно, вам придется проанализировать val () на что-то более значимое, но вы должны быть готовы.


1
это не удастся с FF11 - причина: поскольку вы не можете точно влиять на размер поля ввода (только с помощью размера HTML) и кнопки (вы можете установить высоту с помощью CSS), если видимое поле ввода больше, чем нам предоставляет исходный FF, вы остаются с очень большой слепой зоной - точка зрения пользователя: в большинстве случаев он будет жаловаться, что загрузка не работает при нажатии
Jeffz

2
Хорошая идея, но это не будет работать на IE. $ ('# the_real_file_input'). click () вызовет открытое диалоговое окно, но файл не будет выбран в форме и загрузка не удастся.
Томас

11

Поместите кнопку загрузки файла поверх красивой кнопки или элемента и скройте ее.

Очень просто и будет работать в любом браузере

<div class="upload-wrap">
    <button type="button" class="nice-button">upload_file</button>
    <input type="file" name="file" class="upload-btn">
</div>

Стили

.upload-wrap {
    position: relative;
}

.upload-btn {
    position: absolute;
    left: 0;
    opacity: 0;
}

8

ВИДИМОСТЬ: скрытый трюк

Я обычно иду на visibility:hiddenхитрость

это моя стилизованная кнопка

<div id="uploadbutton" class="btn btn-success btn-block">Upload</div>

это тип ввода = кнопка файла. Обратите внимание на visibility:hiddenправило

<input type="file" id="upload" style="visibility:hidden;">

это бит JavaScript, чтобы склеить их вместе. Оно работает

<script>
 $('#uploadbutton').click(function(){
    $('input[type=file]').click();
 });
 </script>

1
Вы не можете использовать метод click (), чтобы вызвать событие для файла типа ввода. большая часть браузера не позволяет по соображениям безопасности
Махи

даже используя jquery? это верно? как бы ты это сделал вместо этого?
Джанлука Геттини


style="visibility:hidden"слишком долго, просто используйте hidden. Кроме того, click()он работает для любых браузеров, и на данный момент нет очень надежной причины безопасности, и на любых устройствах это законный способ и @Gianluca для классического использования jQuerytrigger()
Thielicious

1
Это именно то решение, которое я собирался добавить к этому! Это работает, и вы можете отобразить его именно так, как вы хотите. Работает с Chrome, попробую другие.
markthewizard1234

7

я могу думать только о том, чтобы найти кнопку с javascript после ее рендеринга и назначить ей стиль

Вы также можете посмотреть на эту рецензию


Чистый CSS, без JavaScript, работает во всех браузерах вплоть до ie7 - потрясающе!
Саймон Стейнбергер,

7
<input type="file" name="media" style="display-none" onchange="document.media.submit()">

Я бы обычно использовал простой javascript для настройки тега ввода файла. Скрытое поле ввода, по нажатию кнопки, вызов javascript скрытого поля, простое решение без использования css или связок jquery.

<button id="file" onclick="$('#file').click()">Upload File</button>

1
Вы не можете использовать click()метод для запуска события для файла ввода типа. большая часть браузера не позволяет по соображениям безопасности.
Махи

6

Здесь мы используем диапазон для запуска ввода файла типа и просто настраиваем этот диапазон , поэтому мы можем добавить любой стиль, используя этот способ.

Запись что мы используем входной тег с параметром visibility: hidden и запускаем его в диапазоне.

.attachFileSpan{
color:#2b6dad;
cursor:pointer;
}
.attachFileSpan:hover{
text-decoration: underline;
}
<h3> Customized input of type file </h3>
<input id="myInput" type="file" style="visibility:hidden"/>

        <span title="attach file" class="attachFileSpan" onclick="document.getElementById('myInput').click()">
        Attach file
        </span>

Ссылка


5

Это хороший способ сделать это с помощью загрузки материала / угловых файлов. Вы можете сделать то же самое с кнопкой начальной загрузки.

Примечание, которое я использовал <a>вместо <button>этого, позволяет всплывать событиям клика.

<label>
    <input type="file" (change)="setFile($event)" style="display:none" />

    <a mat-raised-button color="primary">
      <mat-icon>file_upload</mat-icon>
      Upload Document
    </a>

  </label>

1
Это прекрасно работает в угловых 2+. Не уверен, почему за него проголосовали. Если вы используете угловой, это самое простое решение.
AndrewWhalan

4

ТОЛЬКО CSS

Используйте это очень просто и легко

Html:

<label>Attach your screenshort</label>
                <input type="file" multiple class="choose">

Css:

.choose::-webkit-file-upload-button {
    color: white;
    display: inline-block;
    background: #1CB6E0;
    border: none;
    padding: 7px 15px;
    font-weight: 700;
    border-radius: 3px;
    white-space: nowrap;
    cursor: pointer;
    font-size: 10pt;
}

4

Может быть, много awnsers. Но мне нравится это в чистом CSS с fa-кнопками:

.divs {
    position: relative;
    display: inline-block;
    background-color: #fcc;
}

.inputs {
    position:absolute;
    left: 0px;
    height: 100%;
    width: 100%;
    opacity: 0;
    background: #00f;
    z-index:999;
}

.icons {
    position:relative;
}
<div class="divs">
<input type='file' id='image' class="inputs">
<i class="fa fa-image fa-2x icons"></i>
</div>

<div class="divs">
<input type='file' id='book' class="inputs">
<i class="fa fa-book fa-5x icons"></i>
</div>
<br><br><br>
<div class="divs">
<input type='file' id='data' class="inputs">
<i class="fa fa-id-card fa-3x icons"></i>
</div>





<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>

Скрипка: https://jsfiddle.net/zoutepopcorn/v2zkbpay/1/


4

Не дайте себя одурачить «великолепными» решениями только для CSS, которые на самом деле очень специфичны для браузера, или которые накладываются на стилизованную кнопку поверх реальной кнопки, или которые заставляют вас использовать <label>вместо <button>или любой другой подобный хак , JavaScript необходим, чтобы заставить его работать для общего пользования. Пожалуйста, изучите, как это делают gmail и DropZone, если вы мне не верите.

Просто создайте обычную кнопку по своему усмотрению, затем вызовите простую функцию JS, чтобы создать и связать скрытый элемент ввода с вашей стилизованной кнопкой.

<!DOCTYPE html>
<meta charset="utf-8">

<style>
    button {
        width            : 160px;
        height           : 30px;
        font-size        : 13px;
        border           : none;
        text-align       : center;
        background-color : #444;
        color            : #6f0;
    }
    button:active {
        background-color : #779;
    }
</style>

<button id="upload">Styled upload button!</button>

<script>

function Upload_On_Click(id, handler) {
    var hidden_input = null;
    document.getElementById(id).onclick = function() {hidden_input.click();}
    function setup_hidden_input() {
        hidden_input && hidden_input.parentNode.removeChild(hidden_input);
        hidden_input = document.createElement("input");
        hidden_input.setAttribute("type", "file");
        hidden_input.style.visibility = "hidden";
        document.querySelector("body").appendChild(hidden_input);
        hidden_input.onchange = function() {
            handler(hidden_input.files[0]);
            setup_hidden_input();
        };
    }
    setup_hidden_input();
}

Upload_On_Click("upload", function(file) {
    console.log("GOT FILE: " + file.name);
});

</script>

Обратите внимание, как приведенный выше код пересылает его после каждого выбора пользователем файла. Это важно, потому что «onchange» вызывается, только если пользователь меняет имя файла. Но вы, вероятно, хотите получить файл каждый раз, когда пользователь предоставляет его.


1
Чтобы быть точным, labelподход работает, за исключением того, что он не может показать выбранное имя файла или путь. Итак, обязательно говоря, это единственная проблема, которую нужно решить JS.
Хасан

4

Многофайловое решение с преобразованным именем файла

Пример начальной загрузки

HTML:

<div>
  <label class="btn btn-primary search-file-btn">
    <input name="file1" type="file" style="display:None;"> <span>Choose file</span>
  </label>
  <span>No file selected</span>
</div>

<div>
  <label class="btn btn-primary search-file-btn">
    <input name="file2" type="file" style="display:None;"> <span>Choose file</span>
  </label>
  <span>No file selected</span>
</div>

1. JS с JQuery:

$().ready(function($){
    $('.search-file-btn').children("input").bind('change', function() {
    var fileName = '';
    fileName = $(this).val().split("\\").slice(-1)[0];
    $(this).parent().next("span").html(fileName);
  })
});

2. JS без jQuery

Array.prototype.forEach.call(document.getElementsByTagName('input'), function(item) {
  item.addEventListener("change", function() {
    var fileName = '';
    fileName = this.value.split("\\").slice(-1)[0];
    this.parentNode.nextElementSibling.innerHTML = fileName;
  });
});

3

Вот решение, которое также показывает выбранное имя файла: http://jsfiddle.net/raft9pg0/1/

HTML:

<label for="file-upload" class="custom-file-upload">Chose file</label>
<input id="file-upload" type="file"/>
File: <span id="file-upload-value">-</span>

JS:

$(function() {
    $("input:file[id=file-upload]").change(function() {
        $("#file-upload-value").html( $(this).val() );
    });
});

CSS:

input[type="file"] {
    display: none;
}

.custom-file-upload {
      background: #ddd;
      border: 1px solid #aaa;
      border-top: 1px solid #ccc;
      border-left: 1px solid #ccc;
      -moz-border-radius: 3px;
      -webkit-border-radius: 3px;
      border-radius: 3px;
      color: #444;
      display: inline-block;
      font-size: 11px;
      font-weight: bold;
      text-decoration: none;
      text-shadow: 0 1px rgba(255, 255, 255, .75);
      cursor: pointer;
      margin-bottom: 20px;
      line-height: normal;
      padding: 8px 10px; }

Как отображать только имя файла, а не fakepathпуть?
Хасан

3

На этой неделе мне также потребовалось настроить кнопку и отобразить выбранное имя файла в стороне от нее, поэтому после прочтения некоторых из ответов выше (спасибо BTW) я придумал следующую реализацию:

HTML:

<div class="browse">
<label id="uploadBtn" class="custom-file-upload">Choose file
<input type="file" name="fileInput" id="fileInput" accept=".yaml" ngf-select ngf-change="onFileSelect($files)" />
</label>
<span>{{fileName}}</span>
</div>

CSS

   input[type='file'] {
    color: #a1bbd5;
    display: none;

}

.custom-file-upload {
    border: 1px solid #a1bbd5;
    display: inline-block;
    padding: 2px 8px;
    cursor: pointer;
}

label{
    color: #a1bbd5;
    border-radius: 3px;
}

Javascript (угловой)

app.controller('MainCtrl', function($scope) {

        $scope.fileName = 'No file chosen';

          $scope.onFileSelect = function ($files) {
          $scope.selectedFile = $files;
          $scope.fileName = $files[0].name;
    };
});

По сути, я работаю с библиотекой ng-file-upload, в угловом плане я привязываю имя файла к своему $ scope и присваиваю ему начальное значение «Файл не выбран», я также привязываю функцию onFileSelect () к моя область видимости, поэтому, когда файл выбран, я получаю имя файла с помощью API ng-upload и присваиваю его $ scope.filename.


3

Просто смоделируйте щелчок мышью <input>с помощью trigger()функции при нажатии на стиль <div>. Я создал свою собственную кнопку из <div>и затем нажал на кнопку inputпри нажатии моей <div>. Это позволяет вам создать свою кнопку так, как вы хотите, потому что она <div>и имитирует нажатие на ваш файл <input>. Тогда используйте display: noneна своем <input>.

// div styled as my load file button
<div id="simClick">Load from backup</div>

<input type="file" id="readFile" />

// Click function for input
$("#readFile").click(function() {
    readFile();
});

// Simulate click on the input when clicking div
$("#simClick").click(function() {
    $("#readFile").trigger("click");
});

3

Наилучшим способом является использование псевдоэлемента: after или: before в качестве элемента, перекрывающего ввод de. Затем стилизуйте этот псевдоэлемент по своему желанию. Я рекомендую вам в качестве общего стиля для всех входных файлов сделать следующее:

input {
  height: 0px;
  outline: none;
}

input[type="file"]:before {
  content: "Browse";
  background: #fff;
  width: 100%;
  height: 35px;
  display: block;
  text-align: left;
  position: relative;
  margin: 0;
  margin: 0 5px;
  left: -6px;
  border: 1px solid #e0e0e0;
  top: -1px;
  line-height: 35px;
  color: #b6b6b6;
  padding-left: 5px;
  display: block;
}

3

Лучший способ, который я нашел, это input type: fileустановить его на display: none. Дайте это id. Создайте кнопку или любой другой элемент, который вы хотите открыть файл ввода.

Затем добавьте прослушиватель событий (кнопка), который при нажатии моделирует щелчок по исходному входному файлу. Как нажатие на кнопку с именем «привет», но она открывает окно файла.

Пример кода

//i am using semantic ui

<button class="ui circular icon button purple send-button" id="send-btn">
      <i class="paper plane icon"></i>
    </button>
  <input type="file" id="file" class="input-file" />

Javascript

var attachButton=document.querySelector('.attach-button');
    attachButton.addEventListener('click', e=>{
        $('#file').trigger("click")
    })

2

CSS может многое сделать здесь ... с небольшим обманом ...

<div id='wrapper'>
  <input type='file' id='browse'>
</div>

#wrapper {
     width: 93px; /*play with this value */
     height: 28px; /*play with this value */
     background: url('browseBtn.png') 0 0 no-repeat;
     border:none;
     overflow:hidden;
}

#browse{
     margin-left:-145px; /*play with this value */
     opacity:0; /* set to .5 or something so you can better position it as an overlay then back to zero again after you're done */
     -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
     filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
}

:: ссылка :: http://site-o-matic.net/?viewpost=19

-abbey


2

Я нашел очень простой способ переключить кнопку файла на картинку. Вы просто помечаете картинку и помещаете ее поверх кнопки файла.

<html>
<div id="File button">
    <div style="position:absolute;">
        <!--This is your labeled image-->
        <label for="fileButton"><img src="ImageURL"></label>
    </div>
    <div>
        <input type="file" id="fileButton"/>
    </div>
</div>
</html>

При нажатии на помеченное изображение, вы выбираете кнопку файла.


2

Только такой подход дает вам всю гибкость! ES6 / VanillaJS!

HTML:

<input type="file" style="display:none;"></input>
<button>Upload file</button>

JavaScript:

document.querySelector('button').addEventListener('click', () => {
  document.querySelector('input[type="file"]').click();
});

Это скрывает кнопку входного файла, но под капотом нажимает ее от другой обычной кнопки, которую вы, очевидно, можете стилизовать как любую другую кнопку. Это единственное решение без недостатков, кроме бесполезного DOM-узла. Благодаря display:none;, кнопка ввода не резервирует видимое пространство в DOM.

(Я больше не знаю, кому дать реквизит для этого. Но я получил эту идею где-то здесь, на Stackoverflow.)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.