推特引导表单文件元素上传按钮

为什么没有一个花哨的文件元素上传按钮推特引导?如果为上传按钮实现蓝色的主按钮,那就太好了。它甚至有可能巧妙的上传按钮使用CSS?(看起来像一个无法操纵的本机浏览器元素)

877372 次浏览

设置上传按钮的样式很麻烦,因为它设置的是输入的样式而不是按钮的样式。

但是你可以用这个技巧:

http://www.quirksmode.org/dom/inputfile.html

简介:

  1. 取一个普通的<input type="file">,并将它放在一个带有position: relative的元素中。

  2. 在这个相同的父元素中,添加一个普通的<input>和一个具有正确样式的图像。绝对定位这些元素,使它们占据与<input type="file">相同的位置。

  3. 设置<input type="file">的z-index为2,以便它位于样式化的输入/图像的顶部。

  4. 最后,设置<input type="file">的不透明度为0。<input type="file">现在有效地变得不可见,样式输入/图像闪烁,但你仍然可以点击“浏览”按钮。如果按钮位于图像的顶部,则用户将单击图像并获得正常的文件选择窗口。(注意,你不能使用visibility: hidden,因为一个真正不可见的元素也是不可点击的,我们需要保持可点击)

这是珍妮的自举叉里的。

可以使用。创建简单的上传按钮

<span class="btn btn-file">Upload<input type="file" /></span>
使用fileupload插件,您可以创建更高级的小部件。看一看 # EYZ0 < / p >

对我有用:

更新

# EYZ0:

// Based in: http://duckranger.com/2012/06/pretty-file-input-field-in-bootstrap/
// Version: 0.0.3
// Compatibility with: Bootstrap 3.2.0 and jQuery 2.1.1
// Use:
//     <input class="nice_file_field" type="file" data-label="Choose Document">
//     <script> $(".nice_file_field").niceFileField(); </script>
//
(function( $ ) {
$.fn.niceFileField = function() {
this.each(function(index, file_field) {
file_field = $(file_field);
var label = file_field.attr("data-label") || "Choose File";


file_field.css({"display": "none"});


nice_file_block_text  = '<div class="input-group nice_file_block">';
nice_file_block_text += '  <input type="text" class="form-control">';
nice_file_block_text += '  <span class="input-group-btn">';
nice_file_block_text += '   <button class="btn btn-default nice_file_field_button" type="button">' + label + '</button>';
nice_file_block_text += '  </span>';
nice_file_block_text += '</div>';


file_field.after(nice_file_block_text);


var nice_file_field_button = file_field.parent().find(".nice_file_field_button");
var nice_file_block_element = file_field.parent().find(".nice_file_block");


nice_file_field_button.on("click", function(){ console.log("click"); file_field.click() } );
file_field.change( function(){
nice_file_block_element.find("input").val(file_field.val());
});
});
};
})( jQuery );

不需要额外的插件,这个bootstrap解决方案非常适合我:

<div style="position:relative;">
<a class='btn btn-primary' href='javascript:;'>
Choose File...
<input type="file" style='position:absolute;z-index:2;top:0;left:0;filter: alpha(opacity=0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0;background-color:transparent;color:transparent;' name="file_source" size="40"  onchange='$("#upload-file-info").html($(this).val());'>
</a>
&nbsp;
<span class='label label-info' id="upload-file-info"></span>
</div>

演示:

http://jsfiddle.net/haisumbhatti/cAXFA/1/(引导2)

enter image description here

http://jsfiddle.net/haisumbhatti/y3xyU/(引导3)

enter image description here

这是我喜欢的最好的文件上传风格:

<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="input-append">
<div class="uneditable-input span3"><i class="icon-file fileupload-exists"></i> <span class="fileupload-preview"></span></div><span class="btn btn-file"><span class="fileupload-new">Select file</span><span class="fileupload-exists">Change</span><input type="file" /></span><a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
</div>
</div>

你可以得到演示和更多的风格:

http://www.jasny.net/bootstrap/javascript/#fileinput

但是使用这个,你应该用jasny bootstrap文件替换twitter bootstrap ..

的问候。

不需要花哨的东西:

HTML:

<form method="post" action="/api/admin/image" enctype="multipart/form-data">
<input type="hidden" name="url" value="<%= boxes[i].url %>" />
<input class="image-file-chosen" type="text" />
<br />
<input class="btn image-file-button" value="Choose Image" />
<input class="image-file hide" type="file" name="image"/> <!-- Hidden -->
<br />
<br />
<input class="btn" type="submit" name="image" value="Upload" />
<br />
</form>

JS:

$('.image-file-button').each(function() {
$(this).off('click').on('click', function() {
$(this).siblings('.image-file').trigger('click');
});
});
$('.image-file').each(function() {
$(this).change(function () {
$(this).siblings('.image-file-chosen').val(this.files[0].name);
});
});

注意:所讨论的三个表单元素必须是彼此的兄弟元素(。Image-file-chosen, .image-file-button, .image-file)

这对我来说非常合适

<span>
<input  type="file"
style="visibility:hidden; width: 1px;"
id='${multipartFilePath}' name='${multipartFilePath}'
onchange="$(this).parent().find('span').html($(this).val().replace('C:\\fakepath\\', ''))"  /> <!-- Chrome security returns 'C:\fakepath\'  -->
<input class="btn btn-primary" type="button" value="Upload File.." onclick="$(this).parent().find('input[type=file]').click();"/> <!-- on button click fire the file click event -->
&nbsp;
<span  class="badge badge-important" ></span>
</span>

这是Bootstrap 3,4,5的解决方案。

要制作一个看起来像按钮的功能文件输入控件,你只需要HTML:

超文本标记语言

<label class="btn btn-default">
Browse <input type="file" hidden>
</label>

这适用于所有现代浏览器,包括IE9+。如果你也需要对旧IE的支持,请使用下面所示的遗留方法。

这种技术依赖于HTML5 hidden属性。Bootstrap 4使用以下CSS在不支持的浏览器中填充此特性。如果使用Bootstrap 3,则可能需要添加。

[hidden] {
display: none !important;
}

旧IE的遗留方法

如果您需要IE8及以下版本的支持,请使用以下HTML/CSS:

超文本标记语言

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

CSS

.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;
}

注意,旧的IE不会触发文件输入当你点击<label>,所以CSS "膨胀"做了一些事情来解决这个问题:

  • 使文件输入跨越周围<span>的全宽/高
  • 使文件输入不可见

反馈,更多的阅读

我已经发布了关于这个方法的更多细节,以及如何向用户显示选中了多少文件的示例:

https://www.abeautifulsite.net/posts/whipping-file-inputs-into-shape-with-bootstrap-3/

< a href = " http://markusslima.github。io / bootstrap-filestyle " rel = " http://markusslima.github.io/bootstrap-filestyle/ nofollow”> < / >

$(":file").filestyle();

<input type="file" class="filestyle" data-input="false">
< p > / * *引导3文件样式 * # EYZ0 * *版权所有(c) 2013 Markus Vinicius da Silva Lima *更新引导3保罗恩里克福克斯 * 2.0.0版本 *根据MIT许可证授权。 * * / < / p >
(function ($) {
"use strict";


var Filestyle = function (element, options) {
this.options = options;
this.$elementFilestyle = [];
this.$element = $(element);
};


Filestyle.prototype = {
clear: function () {
this.$element.val('');
this.$elementFilestyle.find(':text').val('');
},


destroy: function () {
this.$element
.removeAttr('style')
.removeData('filestyle')
.val('');
this.$elementFilestyle.remove();
},


icon: function (value) {
if (value === true) {
if (!this.options.icon) {
this.options.icon = true;
this.$elementFilestyle.find('label').prepend(this.htmlIcon());
}
} else if (value === false) {
if (this.options.icon) {
this.options.icon = false;
this.$elementFilestyle.find('i').remove();
}
} else {
return this.options.icon;
}
},


input: function (value) {
if (value === true) {
if (!this.options.input) {
this.options.input = true;
this.$elementFilestyle.prepend(this.htmlInput());


var content = '',
files = [];
if (this.$element[0].files === undefined) {
files[0] = {'name': this.$element[0].value};
} else {
files = this.$element[0].files;
}


for (var i = 0; i < files.length; i++) {
content += files[i].name.split("\\").pop() + ', ';
}
if (content !== '') {
this.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
}
}
} else if (value === false) {
if (this.options.input) {
this.options.input = false;
this.$elementFilestyle.find(':text').remove();
}
} else {
return this.options.input;
}
},


buttonText: function (value) {
if (value !== undefined) {
this.options.buttonText = value;
this.$elementFilestyle.find('label span').html(this.options.buttonText);
} else {
return this.options.buttonText;
}
},


classButton: function (value) {
if (value !== undefined) {
this.options.classButton = value;
this.$elementFilestyle.find('label').attr({'class': this.options.classButton});
if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
this.$elementFilestyle.find('label i').addClass('icon-white');
} else {
this.$elementFilestyle.find('label i').removeClass('icon-white');
}
} else {
return this.options.classButton;
}
},


classIcon: function (value) {
if (value !== undefined) {
this.options.classIcon = value;
if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
this.$elementFilestyle.find('label').find('i').attr({'class': 'icon-white '+this.options.classIcon});
} else {
this.$elementFilestyle.find('label').find('i').attr({'class': this.options.classIcon});
}
} else {
return this.options.classIcon;
}
},


classInput: function (value) {
if (value !== undefined) {
this.options.classInput = value;
this.$elementFilestyle.find(':text').addClass(this.options.classInput);
} else {
return this.options.classInput;
}
},


htmlIcon: function () {
if (this.options.icon) {
var colorIcon = '';
if (this.options.classButton.search(/btn-inverse|btn-primary|btn-danger|btn-warning|btn-success/i) !== -1) {
colorIcon = ' icon-white ';
}


return '<i class="'+colorIcon+this.options.classIcon+'"></i> ';
} else {
return '';
}
},


htmlInput: function () {
if (this.options.input) {
return '<input type="text" class="'+this.options.classInput+'" style="width: '+this.options.inputWidthPorcent+'% !important;display: inline !important;" disabled> ';
} else {
return '';
}
},


constructor: function () {
var _self = this,
html = '',
id = this.$element.attr('id'),
files = [];


if (id === '' || !id) {
id = 'filestyle-'+$('.bootstrap-filestyle').length;
this.$element.attr({'id': id});
}


html = this.htmlInput()+
'<label for="'+id+'" class="'+this.options.classButton+'">'+
this.htmlIcon()+
'<span>'+this.options.buttonText+'</span>'+
'</label>';


this.$elementFilestyle = $('<div class="bootstrap-filestyle" style="display: inline;">'+html+'</div>');


var $label = this.$elementFilestyle.find('label');
var $labelFocusableContainer = $label.parent();


$labelFocusableContainer
.attr('tabindex', "0")
.keypress(function(e) {
if (e.keyCode === 13 || e.charCode === 32) {
$label.click();
}
});


// hidding input file and add filestyle
this.$element
.css({'position':'absolute','left':'-9999px'})
.attr('tabindex', "-1")
.after(this.$elementFilestyle);


// Getting input file value
this.$element.change(function () {
var content = '';
if (this.files === undefined) {
files[0] = {'name': this.value};
} else {
files = this.files;
}


for (var i = 0; i < files.length; i++) {
content += files[i].name.split("\\").pop() + ', ';
}


if (content !== '') {
_self.$elementFilestyle.find(':text').val(content.replace(/\, $/g, ''));
}
});


// Check if browser is Firefox
if (window.navigator.userAgent.search(/firefox/i) > -1) {
// Simulating choose file for firefox
this.$elementFilestyle.find('label').click(function () {
_self.$element.click();
return false;
});
}
}
};


var old = $.fn.filestyle;


$.fn.filestyle = function (option, value) {
var get = '',
element = this.each(function () {
if ($(this).attr('type') === 'file') {
var $this = $(this),
data = $this.data('filestyle'),
options = $.extend({}, $.fn.filestyle.defaults, option, typeof option === 'object' && option);


if (!data) {
$this.data('filestyle', (data = new Filestyle(this, options)));
data.constructor();
}


if (typeof option === 'string') {
get = data[option](value);
}
}
});


if (typeof get !== undefined) {
return get;
} else {
return element;
}
};


$.fn.filestyle.defaults = {
'buttonText': 'Escolher arquivo',
'input': true,
'icon': true,
'inputWidthPorcent': 65,
'classButton': 'btn btn-primary',
'classInput': 'form-control file-input-button',
'classIcon': 'icon-folder-open'
};


$.fn.filestyle.noConflict = function () {
$.fn.filestyle = old;
return this;
};


// Data attributes register
$('.filestyle').each(function () {
var $this = $(this),
options = {
'buttonText': $this.attr('data-buttonText'),
'input': $this.attr('data-input') === 'false' ? false : true,
'icon': $this.attr('data-icon') === 'false' ? false : true,
'classButton': $this.attr('data-classButton'),
'classInput': $this.attr('data-classInput'),
'classIcon': $this.attr('data-classIcon')
};


$this.filestyle(options);
});
})(window.jQuery);

有可接受结果的简单解决办法:

<input type="file" class="form-control">

以及风格:

input[type=file].form-control {
height: auto;
}

我也有同样的问题,我是这样尝试的。

<div>
<button type='button' class='btn btn-info btn-file'>Browse</button>
<input type='file' name='image'/>
</div>

CSS

<style>
.btn-file {
position:absolute;
}
</style>

JS的

<script>
$(document).ready(function(){
$('.btn-file').click(function(){
$('input[name="image"]').click();
});
});
</script>
< p >注意: 按钮.btn-file必须在与输入文件

相同的标签中

希望你找到了最好的解决方案…

我使用http://gregpike.net/demos/bootstrap-file-input/demo.html:

$('input[type=file]').bootstrapFileInput();

$('.file-inputs').bootstrapFileInput();

我很惊讶没有提到<label>元素。

解决方案:

<label class="btn btn-primary" for="my-file-selector">
<input id="my-file-selector" type="file" class="d-none">
Button Text Here
</label>

不需要任何JS,或时髦的css…

包含文件名的解决方案:

<label class="btn btn-primary" for="my-file-selector">
<input id="my-file-selector" type="file" style="display:none"
onchange="$('#upload-file-info').text(this.files[0].name)">
Button Text Here
</label>
<span class='label label-info' id="upload-file-info"></span>

上面的解决方案需要jQuery。

注意:在页面上显示用户提供的内容时使用$.text()。这个答案的早期版本使用了$.html(),这是不安全的-文件名可以包含HTML标记。

从上面的其他文章中得到一些灵感,这里有一个完整的解决方案,它结合了一个看起来像表单控制字段的输入组插件,用于一个干净的文件输入小部件,其中包括到当前文件的链接。

.
.input-file { position: relative; margin: 60px 60px 0 } /* Remove margin, it is just for stackoverflow viewing */
.input-file .input-group-addon { border: 0px; padding: 0px; }
.input-file .input-group-addon .btn { border-radius: 0 4px 4px 0 }
.input-file .input-group-addon input { cursor: pointer; position:absolute; width: 72px; z-index:2;top:0;right:0;filter: alpha(opacity=0);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0; background-color:transparent; color:transparent; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<div class="input-group input-file">
<div class="form-control">
<a href="/path/to/your/current_file_name.pdf" target="_blank">current_file_name.pdf</a>
</div>
<span class="input-group-addon">
<a class='btn btn-primary' href='javascript:;'>
Browse
<input type="file" name="field_name" onchange="$(this).parent().parent().parent().find('.form-control').html($(this).val());">
</a>
</span>
</div>

尝试遵循Bootstrap v.3.3.4

<div>
<input id="uplFile" type="file" style="display: none;">


<div class="input-group" style="width: 300px;">
<div  id="btnBrowse"  class="btn btn-default input-group-addon">Select a file...</div>
<span id="photoCover" class="form-control">
</div>
</div>


<script type="text/javascript">
$('#uplFile').change(function() {
$('#photoCover').text($(this).val());
});


$('#btnBrowse').click(function(){
$('#uplFile').click();
});
</script>

请看推特引导文件输入。 它使用非常简单的解决方案,只需添加一个javascript文件,并粘贴以下代码:

$('input[type=file]').bootstrapFileInput();

使用其他答案的部分简化答案,主要是user2309766和dotcomsuperstar。

特点:

  • 为按钮和字段使用引导按钮插件。
  • 只有一个输入;表单将接收多个输入。
  • 除了"display: none;",没有额外的css来隐藏文件输入。
  • 可见按钮触发隐藏文件输入的单击事件。
  • split删除文件路径使用正则表达式和分隔符'\'和'/'。

代码:

.
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-primary" onclick="$(this).parent().find('input[type=file]').click();">Browse</span>
<input name="uploaded_file" onchange="$(this).parent().parent().find('.form-control').html($(this).val().split(/[\\|/]/).pop());" style="display: none;" type="file">
</span>
<span class="form-control"></span>
</div>

这是另一个技巧,它不是最好的解决方案,但它只是给你一个选择

HTML代码:

<button clss="btn btn-primary" id="btn_upload">Choose File</button>
<input id="fileupload" class="hide" type="file" name="files[]">

Javascript:

$("#btn_upload").click(function(e){
e.preventDefault();
$("#fileupload").trigger('click');
});

我已经创建了一个自定义上传按钮,只接受图像,这可以根据您的要求修改。

希望这能有所帮助!!:)

(已使用的Bootstrap框架)

< a href = " http://codepen。io / ashwinshenoy /钢笔/ BjvyYJ rel =“nofollow”> Codepen-link < / >

超文本标记语言

<center>
<br />
<br />
<span class="head">Upload Button Re-Imagined</span>
<br />
<br />
<div class="fileUpload blue-btn btn width100">
<span>Upload your Organizations logo</span>
<input type="file" class="uploadlogo" />
</div>
</center>

CSS

 .head {
font-size: 25px;
font-weight: 200;
}


.blue-btn:hover,
.blue-btn:active,
.blue-btn:focus,
.blue-btn {
background: transparent;
border: solid 1px #27a9e0;
border-radius: 3px;
color: #27a9e0;
font-size: 16px;
margin-bottom: 20px;
outline: none !important;
padding: 10px 20px;
}


.fileUpload {
position: relative;
overflow: hidden;
height: 43px;
margin-top: 0;
}


.fileUpload input.uploadlogo {
position: absolute;
top: 0;
right: 0;
margin: 0;
padding: 0;
font-size: 20px;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
width: 100%;
height: 42px;
}




/*Chrome fix*/


input::-webkit-file-upload-button {
cursor: pointer !important;
}

JS

// You can modify the upload files to pdf's, docs etc
//Currently it will upload only images
$(document).ready(function($) {


// Upload btn
$(".uploadlogo").change(function() {
readURL(this);
});


function readURL(input) {
var url = input.value;
var ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
if (input.files && input.files[0] && (ext == "png" || ext == "jpeg" || ext == "jpg" || ext == "gif" || ext == "svg")) {
var path = $('.uploadlogo').val();
var filename = path.replace(/^.*\\/, "");
$('.fileUpload span').html('Uploaded logo : ' + filename);
// console.log(filename);
} else {
$(".uploadlogo").val("");
$('.fileUpload span').html('Only Images Are Allowed!');
}
}
});

我修改了@claviska的答案,并按照我喜欢的方式工作(Bootstrap 3,4未测试):

<label class="btn btn-default">
<span>Browse</span>
<input type="file" style="display: none;" onchange="$(this).prev('span').text($(this).val()!=''?$(this).val():'Browse')">
</label>

enter image description here

下面的代码与上面的图片一样

超文本标记语言

<form>
<div class="row">
<div class="col-lg-6">
<label for="file">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Browse</button>
</span>
<input type="text" class="form-control" id="info" readonly="" style="background: #fff;" placeholder="Search for...">
</div><!-- /input-group -->
</label>
</div><!-- /.col-lg-6 -->
</div>


</div>
<input type="file" style="display: none;" onchange="$('#info').val($(this).val().split(/[\\|/]/).pop()); " name="file" id="file">
</form>

Javascript

<script type="text/javascript">


$(function() {
$("label[for=file]").click(function(event) {
event.preventDefault();
$("#file").click();
});
});


</script>

多重上传解决方案

我调整了之前的两个答案,包括多次上传。通过这种方式,如果只选择一个,则标签显示文件名,反之则是x files

<label class="btn btn-primary" for="my-file-selector">
<input id="my-file-selector" type="file" multiple="multiple" style="display:none"
onchange="$('#upload-file-info').html(
(this.files.length > 1) ? this.files.length + ' files' : this.files[0].name)">
Files&hellip;
</label>
<span class='label label-info' id="upload-file-info"></span>

enter image description here

它也可以应用于更改按钮文本和类。

<label class="btn btn-primary" for="multfile">
<input id="multfile" type="file" multiple="multiple" style="display:none"
onchange="$('#multfile-label').html(
(this.files.length == 1) ? this.files[0].name : this.files.length + ' files');
$(this).parent().addClass('btn-success')">
<span id="multfile-label">Files&hellip;</span>
</label>

enter image description here

关于claviska的答案-如果你想在一个基本的文件上传中显示上传的文件名,你可以在input的onchange事件中做。只需使用以下代码:

 <label class="btn btn-default">
Browse...
<span id="uploaded-file-name" style="font-style: italic"></span>
<input id="file-upload" type="file" name="file"
onchange="$('#uploaded-file-name').text($('#file-upload')[0].value);" hidden>
</label>

这个jquery JS代码负责检索上传的文件名:

$('#file-upload')[0].value

或者用香草JS:

document.getElementById("file-upload").value

example

我想我应该加上我的三便士价值,只是说如何默认的.custom-file-labelcustom-file-input BS4文件输入,以及如何使用它。

后一个类在输入组上,是不可见的。而前者是可见标签,并且有一个:后伪元素,看起来像一个按钮。

<div class="custom-file">
<input type="file" class="custom-file-input" id="upload">
<label class="custom-file-label" for="upload">Choose file</label>
</div>

你不能向伪元素中添加类,但是你可以用CSS(或SASS)来设置它们的样式。

.custom-file-label:after {
color: #fff;
background-color: #1e7e34;
border-color: #1c7430;
pointer: cursor;
}

基于绝对聪明的@claviska解决方案,所有的功劳都要归功于他。

全功能的Bootstrap 4文件输入验证和帮助文本。

基于输入组示例,我们有一个用于向用户显示文件名的虚拟输入文本字段,该字段由隐藏在标签按钮后面的实际输入文件字段上的onchange事件填充。除了包含Bootstrap验证支持外,我们还可以点击输入中的任何地方来打开文件对话框。

文件输入的三种状态

这三种可能的状态是未验证的、有效的和无效的,设置了虚拟html输入标记属性required

enter image description here

Html标记作为输入

我们只引入了input-file-dummyinput-file-btn两个自定义类来正确地设置样式并连接所需的行为。其他的都是标准的Bootstrap 4标记。

<div class="input-group">
<input type="text" class="form-control input-file-dummy" placeholder="Choose file" aria-describedby="fileHelp" required>
<div class="valid-feedback order-last">File is valid</div>
<div class="invalid-feedback order-last">File is required</div>
<label class="input-group-append mb-0">
<span class="btn btn-primary input-file-btn">
Browse… <input type="file" hidden>
</span>
</label>
</div>
<small id="fileHelp" class="form-text text-muted">Choose any file you like</small>

JavaScript行为规定

虚拟输入需要是只读的,就像原来的例子一样,以防止用户更改只能通过打开文件对话框更改的输入。不幸的是,验证不会发生在readonly字段上,所以我们切换了焦点和模糊输入的可编辑性(jquery的事件 onfocusinonfocusout),并确保一旦文件被选中,它就可以再次验证。

除了使文本字段可单击之外,通过触发按钮的单击事件,填充虚拟字段的其余功能是由@claviska设想的。

$(function () {
$('.input-file-dummy').each(function () {
$($(this).parent().find('.input-file-btn input')).on('change', {dummy: this}, function(ev) {
$(ev.data.dummy)
.val($(this).val().replace(/\\/g, '/').replace(/.*\//, ''))
.trigger('focusout');
});
$(this).on('focusin', function () {
$(this).attr('readonly', '');
}).on('focusout', function () {
$(this).removeAttr('readonly');
}).on('click', function () {
$(this).parent().find('.input-file-btn').click();
});
});
});

自定义样式调整

最重要的是,我们不希望readonly字段在灰色背景和白色之间跳跃,所以我们确保它保持白色。span按钮没有指针光标,但我们需要为输入添加一个指针光标。

.input-file-dummy, .input-file-btn {
cursor: pointer;
}
.input-file-dummy[readonly] {
background-color: white;
}

nJoy !