你如何风格输入类型=“文件”按钮?

<输入类型=“文件” />


当前回答

你不需要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>

在样式方面,只需使用属性选择器隐藏输入元素。

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

然后,您所需要做的就是设置自定义标签元素的样式。(例子)。

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

1 -值得注意的是,如果你使用display: none隐藏元素,它将在IE8及以下版本中不起作用。还要注意,jQuery验证默认情况下不验证隐藏字段。如果这两种情况对您来说是一个问题,这里有两种不同的方法来隐藏输入(1,2),在这种情况下可以工作。

其他回答

如果有人仍然关心如何在没有JavaScript的情况下做到这一点,让我完成Josh的回答:

如何显示文件名的文本:

最简单的方法是将这两个元素设置到一个位置:相对,给标签一个更高的z-index,并给输入文件负边距,直到标签文本在你想要的位置。不要在输入时使用display:none !

例子:

input[type="file"] {
  position:relative;
  z-index:1;
  margin-left:-90px;
}

.custom-file-upload {
  border: 1px solid #ccc;
  display: inline-block;
  padding: 6px 12px;
  cursor: pointer;
  position:relative;
  z-index:2;
  background:white;

}

不要被“伟大的”css解决方案所欺骗,这些解决方案实际上非常特定于浏览器,或者将样式化按钮覆盖在真正的按钮之上,或者强迫您使用<label>而不是<button>,或任何其他类似的hack。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"。但您可能希望在用户每次提供该文件时获取该文件。

转换文件名的多个文件解决方案

自举例子

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. jQuery JS:

$().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;
  });
});

CSS在这里可以做很多事情…耍点小花招……

<div id='wrapper'>
    <input type='file' id='browse'>
</div>
<style>
    #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);
    }
</style>

::参考::http://site-o-matic.net/?viewpost=19

修道院

当点击有样式的<div>时,只需使用trigger()函数模拟点击<input>。我在<div>中创建了自己的按钮,然后在点击我的<div>时触发了输入上的单击。这允许你创建你想要的按钮,因为它是一个<div>,模拟点击你的文件<input>。然后在<input>上使用display: none。

// 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");
});