如何自定义<input type="file">?

209

能否改变 <input type="file"> 元素的外观?


文本字段的存在是因为它可以在用户浏览并选择文件后显示文件路径。 - k to the z
哎呀,看来这是Firefox的处理方式... - Newbie Coder
只是为了明确,即使他们浏览文件后,仍然需要使用表单提交按钮提交表单。 - k to the z
18个回答

4

如果您只使用 <label>,隐藏 <input> 并自定义标签,效果会更好。

HTML:

<input type="file" id="input">
<label for="input" id="label">Choose File</label>

CSS:

input#input{
    display: none;
}
label#label{
    /* Customize your label here */
}

1
display: none 将从选项卡顺序中删除该元素。使用 <label>(如 Tympanus 所示)是语义上正确的方式,但需要一些改进。此外,这个问题几年后又被问到了,并且有更好的答案:跨浏览器自定义文件上传按钮样式 - Dan Dascalescu

4
要显示所选文件的路径,您可以尝试在HTML上执行以下操作:
<div class="fileinputs">
    <input type="file" class="file">
</div>

在 JavaScript 中:
        var fakeFileUpload = document.createElement('div');
        fakeFileUpload.className = 'fakefile';
        var image = document.createElement('div');
        image.className='fakebtn';
        image.innerHTML = 'browse';
        fakeFileUpload.appendChild(image);
        fakeFileUpload.appendChild(document.createElement('input'));
        var x = document.getElementsByTagName('input');
        for (var i=0;i<x.length;i++) {
            if (x[i].type != 'file') continue;
            if (x[i].parentNode.className != 'fileinputs') continue;
            x[i].className = 'file hidden';
            var clone = fakeFileUpload.cloneNode(true);
            x[i].parentNode.appendChild(clone);
            x[i].relatedElement = clone.getElementsByTagName('input')[0];
            x[i].onchange = x[i].onmouseout = function () {
                this.relatedElement.value = this.value;
            }
        }

并且样式:

div.fileinputs {
    position: relative;
    height: 30px;
    width: 370px;
}
input.file.hidden {
    position: relative;
    text-align: right;
    -moz-opacity: 0;
    filter: alpha(opacity: 0);
    opacity: 0;
    z-index: 2;
}
div.fakefile {
    position: absolute;
    top: 0px;
    left: 0px;
    right: 0;
    width: 370px;
    padding: 0;
    margin: 0;
    z-index: 1;
    line-height: 90%;
}
div.fakefile input {
    margin-bottom: 5px;
    margin-left: 0;
    border: none;
    box-shadow: 0px 0px 2px 1px #ccc;
    padding: 4px;
    width: 241px;
    height: 20px;
}
div.fakefile .fakebtn{
    width: 150px;
    background: #eb5a41;
    z-index: 10;
    font-family: roya-bold;
    border: none;
    padding: 5px 15px;
    font-size: 18px;
    text-align: center;
    cursor: pointer;
    -webkit-transition: all 0.4s ease;
    -moz-transition: all 0.4s ease;
    -o-transition: all 0.4s ease;
    -ms-transition: all 0.4s ease;
    transition: all 0.4s ease;
    display: inline;
    margin-left: 3px;
}
div.fileinputs input[type="file"]:hover + div .fakebtn{
    background: #DA472E;
}

div.fileinputs input[type="file"] {
    opacity: 0;
    position: absolute;
    top: -6px;
    right: 0px;
    z-index: 20;
    width: 102px;
    height: 40px;
    cursor: pointer;
}

2

 $(document).ready(function () {
        $(document).mousemove(function () {
        $('#myList').css('display', 'block');
        $("#seebtn").css('display', 'none');
        $("#hidebtn").css('display', 'none');
        $('#displayFileNames').html('');
        $("#myList").html('');
        var fileArray1 = document.getElementsByClassName('file-input');
        for (var i = 0; i < fileArray1.length; i++) {
            var files = fileArray1[i].files;
            for (var j = 0; j < files.length; j++) {
                $("#myList").append("<li style='color:black'>" + files[j].name + "</li>");
            }
        };

        if (($("#myList").html()) != '') {
            $('#unselect').css('display', 'block');
            $('#divforfile').css('color', 'green');
            $('#attach').css('color', 'green');
            $('#displayFileNames').html($("#myList").children().length + ' ' + 'files selezionato');

        };

        if (($("#myList").html()) == '') {
            $('#divforfile').css('color', 'black');
            $('#attach').css('color', 'black');
            $('#displayFileNames').append('Nessun File Selezionato');
        };
    });

  });

  function choosefiles(obj) {
        $(obj).hide();
        $('#myList').css('display', 'none');
        $('#hidebtn').css('display', 'none');
        $("#seebtn").css('display', 'none');
        $('#unselect').css('display', 'none');
        $("#upload-form").append("<input class='file-input inputs' type='file' onclick='choosefiles(this)' name='file[]' multiple='multiple' />");
        $('#displayFileNames').html('');
    }

  $(document).ready(function () {
        $('#unselect').click(function () {
            $('#hidebtn').css('display', 'none');
            $("#seebtn").css('display', 'none');
            $('#displayFileNames').html('');
            $("#myList").html('');
            $('#myFileInput').val('');
            document.getElementById('upload-form').reset();         
            $('#unselect').css('display', 'none');
            $('#divforfile').css('color', 'black');
            $('#attach').css('color', 'black');

        });
    });
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
  .divs {
        position: absolute;
        display: inline-block;
        background-color: #fff;
    }

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

    .icons {
        position: absolute;
    }

 </style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
            <div>
                <form id='upload-form' action='' method='post' enctype='multipart/form-data'>
                   
                    <div class="divs" id="divforfile" style="color:black">
                        <input id='myFileInput' class='file-input inputs' type='file' name='file[]' onclick="choosefiles(this)" multiple='multiple' />
                        <i class="material-icons" id="attach" style="font-size:21px;color:black">attach_file</i><label>Allegati</label>
                    </div>
                </form>
                <br />
            </div>
            <br />  
            <div>
                <button style="border:none; background-color:white; color:black; display:none" id="seebtn"><p>Files &#9660;</p></button>
                <button style="border:none; background-color:white; color:black; display:none" id="hidebtn"><p>Files &#9650;</p></button>
                <button type="button" class="close" aria-label="Close" id="unselect" style="display:none;float:left">
                    <span style="color:red">&times;</span>
                </button>
                <div id="displayFileNames">
                </div>
                <ul id="myList"></ul>
            </div>

这是我使用jQuery和JavaScript(Visual Studio)开发的完全功能的定制文件上传/附件。这将非常有用!
代码将在评论部分提供!
链接:https://youtu.be/It38OzMAeig 享受 :)

 $(document).ready(function () {
        $(document).mousemove(function () {
        $('#myList').css('display', 'block');
        $("#seebtn").css('display', 'none');
        $("#hidebtn").css('display', 'none');
        $('#displayFileNames').html('');
        $("#myList").html('');
        var fileArray1 = document.getElementsByClassName('file-input');
        for (var i = 0; i < fileArray1.length; i++) {
            var files = fileArray1[i].files;
            for (var j = 0; j < files.length; j++) {
                $("#myList").append("<li style='color:black'>" + files[j].name + "</li>");
            }
        };

        if (($("#myList").html()) != '') {
            $('#unselect').css('display', 'block');
            $('#divforfile').css('color', 'green');
            $('#attach').css('color', 'green');
            $('#displayFileNames').html($("#myList").children().length + ' ' + 'files selezionato');

        };

        if (($("#myList").html()) == '') {
            $('#divforfile').css('color', 'black');
            $('#attach').css('color', 'black');
            $('#displayFileNames').append('Nessun File Selezionato');
        };
    });

  });

  function choosefiles(obj) {
        $(obj).hide();
        $('#myList').css('display', 'none');
        $('#hidebtn').css('display', 'none');
        $("#seebtn").css('display', 'none');
        $('#unselect').css('display', 'none');
        $("#upload-form").append("<input class='file-input inputs' type='file' onclick='choosefiles(this)' name='file[]' multiple='multiple' />");
        $('#displayFileNames').html('');
    }

  $(document).ready(function () {
        $('#unselect').click(function () {
            $('#hidebtn').css('display', 'none');
            $("#seebtn").css('display', 'none');
            $('#displayFileNames').html('');
            $("#myList").html('');
            $('#myFileInput').val('');
            document.getElementById('upload-form').reset();         
            $('#unselect').css('display', 'none');
            $('#divforfile').css('color', 'black');
            $('#attach').css('color', 'black');

        });
    });
<style>
  .divs {
        position: absolute;
        display: inline-block;
        background-color: #fff;
    }

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

    .icons {
        position: absolute;
    }

 </style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
   <div>
                <form id='upload-form' action='' method='post' enctype='multipart/form-data'>
                   
                    <div class="divs" id="divforfile" style="color:black">
                        <input id='myFileInput' class='file-input inputs' type='file' name='file[]' onclick="choosefiles(this)" multiple='multiple' />
                        <i class="material-icons" id="attach" style="font-size:21px;color:black">attach_file</i><label>Allegati</label>
                    </div>
                </form>
                <br />
            </div>
            <br />  
            <div>
                <button style="border:none; background-color:white; color:black; display:none" id="seebtn"><p>Files &#9660;</p></button>
                <button style="border:none; background-color:white; color:black; display:none" id="hidebtn"><p>Files &#9650;</p></button>
                <button type="button" class="close" aria-label="Close" id="unselect" style="display:none;float:left">
                    <span style="color:red">&times;</span>
                </button>
                <div id="displayFileNames">
                </div>
                <ul id="myList"></ul>
            </div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
 $(document).ready(function () {
        $(document).mousemove(function () {
        $('#myList').css('display', 'block');
        $("#seebtn").css('display', 'none');
        $("#hidebtn").css('display', 'none');
        $('#displayFileNames').html('');
        $("#myList").html('');
        var fileArray1 = document.getElementsByClassName('file-input');
        for (var i = 0; i < fileArray1.length; i++) {
            var files = fileArray1[i].files;
            for (var j = 0; j < files.length; j++) {
                $("#myList").append("<li style='color:black'>" + files[j].name + "</li>");
            }
        };

        if (($("#myList").html()) != '') {
            $('#unselect').css('display', 'block');
            $('#divforfile').css('color', 'green');
            $('#attach').css('color', 'green');
            $('#displayFileNames').html($("#myList").children().length + ' ' + 'files selezionato');

        };

        if (($("#myList").html()) == '') {
            $('#divforfile').css('color', 'black');
            $('#attach').css('color', 'black');
            $('#displayFileNames').append('Nessun File Selezionato');
        };
    });

  });

  function choosefiles(obj) {
        $(obj).hide();
        $('#myList').css('display', 'none');
        $('#hidebtn').css('display', 'none');
        $("#seebtn").css('display', 'none');
        $('#unselect').css('display', 'none');
        $("#upload-form").append("<input class='file-input inputs' type='file' onclick='choosefiles(this)' name='file[]' multiple='multiple' />");
        $('#displayFileNames').html('');
    }

  $(document).ready(function () {
        $('#unselect').click(function () {
            $('#hidebtn').css('display', 'none');
            $("#seebtn").css('display', 'none');
            $('#displayFileNames').html('');
            $("#myList").html('');
            $('#myFileInput').val('');
            document.getElementById('upload-form').reset();         
            $('#unselect').css('display', 'none');
            $('#divforfile').css('color', 'black');
            $('#attach').css('color', 'black');

        });
    });
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
  .divs {
        position: absolute;
        display: inline-block;
        background-color: #fff;
    }

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

    .icons {
        position: absolute;
    }

 </style>
 <div>
                <form id='upload-form' action='' method='post' enctype='multipart/form-data'>
                   
                    <div class="divs" id="divforfile" style="color:black">
                        <input id='myFileInput' class='file-input inputs' type='file' name='file[]' onclick="choosefiles(this)" multiple='multiple' />
                        <i class="material-icons" id="attach" style="font-size:21px;color:black">attach_file</i><label>Allegati</label>
                    </div>
                </form>
                <br />
            </div>
            <br />  
            <div>
                <button style="border:none; background-color:white; color:black; display:none" id="seebtn"><p>Files &#9660;</p></button>
                <button style="border:none; background-color:white; color:black; display:none" id="hidebtn"><p>Files &#9650;</p></button>
                <button type="button" class="close" aria-label="Close" id="unselect" style="display:none;float:left">
                    <span style="color:red">&times;</span>
                </button>
                <div id="displayFileNames">
                </div>
                <ul id="myList"></ul>
            </div>


1
我选择了这个选项,它通过包含一个已上传文件名的处理程序来澄清如何完全自定义浏览按钮,还进行了定制。 它添加了额外的字段和客户端控件,只是为了展示如何在“真正”的表单中包含浏览,而不仅仅是独立的。 这是代码pen: http://codepen.io/emiemi/pen/zxNXWR JS:
//click on our custom btn triggers a click on the hidden actual file input 
$("#btnup").click(function(){
   $("#fileup").click();    
});


//changes on the three fields (input, tit,and name) trigger a control which checks if the 3 fields are all filled and if file field is valid (an image is uploaded)
$('#fileup').change(function(){
    var formDOMObj = document.upload;
//here we assign tu our text field #fileup the name of the selected file  
    var res=$('#fileup').val();
    var arr = res.split("\\");
//if file is not valid we show the error icon and the red alert
    if (formDOMObj.fileup.value.indexOf(".jpg") == -1 && formDOMObj.fileup.value.indexOf(".png") == -1 &&  formDOMObj.fileup.value.indexOf(".jpeg") == -1 && formDOMObj.fileup.value.indexOf(".bmp") == -1 && formDOMObj.fileup.value.indexOf(".JPG") == -1 && formDOMObj.fileup.value.indexOf(".PNG") == -1 &&  formDOMObj.fileup.value.indexOf(".JPEG") == -1 && formDOMObj.fileup.value.indexOf(".BMP") == -1){
        $( ".imgupload" ).hide("slow"); 
        $( ".imguploadok" ).hide("slow");   
        $( ".imguploadstop" ).show("slow");
        $('#nomefile').css({"color":"red","font-weight":700});
        $('#nomefile').html("The file "+arr.slice(-1)[0]+" is not an image!");
        $( "#bottone" ).hide();
        $( "#fakebtn" ).show();
    }else{
 //if file is valid we show the green alert
    $( ".imgupload" ).hide("slow");
    $( ".imguploadstop" ).hide("slow");
    $( ".imguploadok" ).show("slow");
    $('#nomefile').html(arr.slice(-1)[0]);
    $('#nomefile').css({"color":"green","font-weight":700});
    if (formDOMObj.nome.value!=""&&formDOMObj.tit.value!=""&&formDOMObj.fileup.value!=""){
  //if all three fields are valid the fake input btn is hidden and the actual one i s finally hown
        $( "#fakebtn" ).hide();
        $( "#bottone" ).show();
    }
    }
});


$('#nome').change(function(){
//same as file change but on name field
    var formDOMObj = document.upload;
    if (formDOMObj.nome.value!=""&&formDOMObj.tit.value!=""&&formDOMObj.fileup.value!=""){
        $( "#fakebtn" ).hide();
        $( "#bottone" ).show();
    }else{
        $( "#bottone" ).hide();
        $( "#fakebtn" ).show();
    }
});
$('#tit').change(function(){
 //same as file change but on tit field
    var formDOMObj = document.upload;
    if (formDOMObj.nome.value!=""&&formDOMObj.tit.value!=""&&formDOMObj.fileup.value!=""){
        $( "#fakebtn" ).hide();
        $( "#bottone" ).show();
    }else{
        $( "#bottone" ).hide();
        $( "#fakebtn" ).show();
    }
});

HTML:

<form name="upload" method="post" action="/" enctype="multipart/form-data" accept-charset="utf-8">
<div class="row">
  <div class="col-md-6 center">
<!--this is the actual file input, s hidden beacause we wanna use our custom one-->
    <input type="file" value="" class="hidden" name="fileup" id="fileup">
    <div class="btn-container">
<!--the three icons: default, ok file (img), error file (not an img)-->
      <h1 class="imgupload"><i class="fa fa-file-image-o"></i></h1>
      <h1 class="imguploadok"><i class="fa fa-check"></i></h1>
      <h1 class="imguploadstop"><i class="fa fa-times"></i></h1>
<!--this field changes dinamically displaying the filename we are trying to upload-->
      <p id="nomefile">Only pics allowed! (jpg,jpeg,bmp,png)</p>
<!--our custom btn which triggers the actual hidden one-->
      <button type="button" id="btnup" class="btn btn-primary btn-lg">Browse for your pic!</button>
    </div>
  </div>
<!--additional fields-->
  <div class="col-md-6">
    <div class="row">
      <div class="form-group" id="top">
        <div class="col-md-12">
          <input type="text" maxlength="100" class="form-control" name="nome" id="nome" placeholder="Your Name">
        </div>
      </div>
    </div>
    <div class="row">
      <div class="form-group">
        <div class="col-md-12">
          <input type="text" maxlength="50" class="form-control" name="tit" id="tit" placeholder="I am rubber, you are glue">
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-md-8">
        <p class="white">All fields are mandatory</p>
      </div>
      <div class="col-md-4">
<!--the defauld disabled btn and the actual one shown only if the three fields are valid-->
        <input type="submit" value="Submit!" class="btn btn-primary" id="bottone" style="padding-left:50px; padding-right:50px; display:none;">
        <button type="button" class="btn btn-default" disabled="disabled" id="fakebtn"  style="padding-left:40px; padding-right:40px;">Submit! <i class="fa fa-minus-circle"></i></button>
      </div>
    </div>
  </div>
</div>


1

我喜欢这种方式,因为它可以使输入填满整个容器。诀窍在于“字体大小:100px”,它需要与“溢出:隐藏”和相对位置一起使用。

<div id="upload-file-container" >
   <input type="file" />
</div>

#upload-file-container {
   width: 200px;
   height: 50px;
   position: relative;
   border: dashed 1px black;
   overflow: hidden;
}

#upload-file-container input[type="file"]
{
   margin: 0;
   opacity: 0;   
   font-size: 100px;
}

最好将其设置为 position: absolute; right: 0; font-size: <many>px; - x-yuri

0

只需使用您喜欢的CSS样式化普通按钮。

然后调用一个简单的JS函数来创建并链接一个隐藏的输入元素到您样式化的按钮。不要添加特定于浏览器的CSS来进行隐藏部分。

<!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”。但您可能希望每次用户提供文件时都获取该文件。
有关更多详细信息,请研究DropZone和gmail上传。

0

你可以为它们添加样式,但是无法移除已经存在的元素。如果你有创意,可以利用这一点做出类似于这样的效果:

input[type=file] {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background: #EEE;
    background: linear-gradient(to top, #FFF, #DDD);
    border: thin solid rgba(0,0,0, .5);
    border-radius: .25em;
    box-shadow: inset .25em .25em .25em rgba(255,255,255, .5), inset -.1em -.1em .1em rgba(0,0,0, 0.1);
    cursor: text;
    padding: .25em;
}

http://jsfiddle.net/zr1x1m2b/1/

我建议你尝试着玩弄这段代码,删除一些行,添加自己的内容,直到你得到一个你喜欢的样子为止!

1
不要为“选择文件”这几个单词设置样式。使用<label>(如Tympanus所示)是语义化的,并提供完全的可定制性。此外,这个问题在几年后又被问到了,那里有更好的答案:跨浏览器自定义文件上传按钮样式 - Dan Dascalescu
1
@DanDascalescu 没错!我只是提供了一个纯CSS的解决方案,以防您无法更改HTML设置。 - Ky -

-2

这是我最近发现的一种方法,需要使用一点jQuery。

HTML代码:

<form action="">
    <input type="file" name="file_upload" style="display:none" id="myFile">

    <a onclick="fileUpload()"> Upload a file </a>
</form>

对于 JavaScript/jQuery 部分:

<script>
function fileUpload() {
    $("#myFile").click();
}
</script>

在这个例子中,我放置了一个“锚点”标签来触发文件上传。你可以用任何你想要的东西来替换它,只要记得用正确的函数放置“onclick”属性即可。
希望这能帮到你!
附注:不要忘记从CDN或其他来源包含jQuery。

display: none 将从选项卡顺序中移除输入。使用 <label>(如 Tympanus 所示)更具语义性,不会出现 hacky 的情况。此外,这个问题几年后又被问到,并且有更好的答案:跨浏览器自定义文件上传按钮样式 - Dan Dascalescu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接