更改input type="file"中的默认文本?

308

我想更改在使用 input="file" 时,按钮上的默认文本为 "选择文件"。

输入图像描述

我该如何做?另外,正如您在图像中看到的,按钮位于文本的左侧。我该如何将它放在文本的右侧?


有没有选项可以将这个文本存储到变量中? - kicaj
2
这里ParPar的回答可能是你要找的:https://dev59.com/yXI-5IYBdhLWcg3wQV8Z。 - Aniket Suryavanshi
可能是如何重命名input type=file的HTML“浏览”按钮?的重复问题。关于样式的一般性问题:https://dev59.com/dXRB5IYBdhLWcg3wn4UL - Ciro Santilli OurBigBook.com
尝试这个解决方案:http://stackoverflow.com/a/30275263/1657573 - Michael Tarimo
可能是重复的问题:如何更改<input type="file"/>按钮文本? - Bae
24个回答

3

更新2017:

我已经研究了如何实现这个功能。最好的解释和教程在这里: https://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/

如果链接不可用,我将在此处写下摘要。所以你应该有HTML代码:

<input type="file" name="file" id="file" class="inputfile" />
<label for="file">Choose a file</label>

接下来使用CSS隐藏该输入框:

.inputfile {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;}

然后,对标签进行样式设置:
.inputfile + label {
font-size: 1.25em;
font-weight: 700;
color: white;
background-color: black;
display: inline-block;
}

然后你可以选择添加JS来显示文件名:

var inputs = document.querySelectorAll( '.inputfile' );
Array.prototype.forEach.call( inputs, function( input )
{
var label    = input.nextElementSibling,
    labelVal = label.innerHTML;

input.addEventListener( 'change', function( e )
{
    var fileName = '';
    if( this.files && this.files.length > 1 )
        fileName = ( this.getAttribute( 'data-multiple-caption' ) || '' ).replace( '{count}', this.files.length );
    else
        fileName = e.target.value.split( '\\' ).pop();

    if( fileName )
        label.querySelector( 'span' ).innerHTML = fileName;
    else
        label.innerHTML = labelVal;
});
});

但实际上只需要阅读教程和下载演示,这非常不错。


3
使用Bootstrap,您可以像下面的代码一样完成此操作。
<!DOCTYPE html>
<html lang="en">
<head>

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

  </style>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
  <span class="btn btn-file">Upload image from here<input type="file">
</body>
</html>

这段代码没有将选择的文件打印回网页。 - tale852150

3

这应该可以工作:

input.*className*::-webkit-file-upload-button {
  *style content..*
}

3

以下是使用Bootstrap完成的步骤,您只需要将原始输入放在某个地方即可...我不确定是否在head中并删除 <br>,因为它只是隐藏了而已,而且也会占用空间 :)

 <head> 
 <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
 </head>
 
 <label for="file" button type="file" name="image" class="btn btn-secondary">Secondary</button> </label>
    
 <input type="file" id="file" name="image" value="Prebrskaj" style="visibility:hidden;">
 
 
 <footer>
 
 <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
 
 </footer>


3

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <button style="display:block;width:120px; height:30px;" onclick="document.getElementById('getFile').click()">Your text here</button>
  <input type='file' id="getFile" style="display:none">
</body>

</html>


2
我编写了一个脚本,可以更轻松地完成这项工作。
例如:

<input data-com="fileBtn" placeholder="选择图片">

基本上,我的脚本与这个链接非常相似。
代码
纯 JavaScript,不需要任何依赖。

<!-- bootstrap.min.css not necessary -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.0/css/bootstrap.min.css">

<input data-com="fileBtn" placeholder="Select Image"> <!-- com: components -->
<input data-com="fileBtn" placeholder="Select File">
<div class="mt-2">
<input id="build-by-myself" placeholder="Select Video" accept="video/mp4, video/webm">
<div>

<script>
  //  Test
  (()=>{
    window.onload = () =>{
      // FileButton.className ="btn btn-danger"
      FileButton.BuildAll() // auto build all data-com="fileBtn"
      
      // or you can specify the target that you wanted.
      new FileButton(document.getElementById("build-by-myself"), "btn btn-danger")
    }
  })()

  //  script begin
  class FileButton {
    static className = "btn btn-primary"
    static BuildAll() {
      document.querySelectorAll(`input[data-com="fileBtn"]`).forEach(input=>{
        new FileButton(input, FileButton.className)
      })
    }
    /**
     * @param {HTMLInputElement} input
     * @param {string} btnClsName
     * */
    constructor(input, btnClsName) {
      input.style.display = "none" // [display is better than visibility](https://dev59.com/V3VC5IYBdhLWcg3w-WOs#48495293)
      input.type = "file"
      const frag = document.createRange().createContextualFragment(`<button class="${btnClsName}">${input.placeholder}</button>`)
      const button = frag.querySelector(`button`)

      input.parentNode.insertBefore(frag, input)

      button.onclick = ()=>{
        input.click()
      }
      input.addEventListener(`change`, (e)=>{
        // create a textNode to show the file name.
        const file = input.files[0]
        if (file === undefined) {
          return
        }
        const textNode = document.createTextNode(file.name)
        if (button.textNode) { // create a new attribute to record previous data.
          button.textNode.remove()
        }
        button.textNode = textNode
        button.parentNode.insertBefore(textNode, input)
      })
    }
  }
</script>

参考资料


绝对是最好的解决方案 - undefined

2

My solution...

HTML :

<input type="file" id="uploadImages" style="display:none;" multiple>

<input type="button" id="callUploadImages" value="Select">
<input type="button" id="uploadImagesInfo" value="0 file(s)." disabled>
<input type="button" id="uploadProductImages" value="Upload">

Jquery:

$('#callUploadImages').click(function(){

    $('#uploadImages').click();
});

$('#uploadImages').change(function(){

    var uploadImages = $(this);
    $('#uploadImagesInfo').val(uploadImages[0].files.length+" file(s).");
});

This is just evil :D


1
我会使用一个来触发输入框:
<button onclick="document.getElementById('fileUpload').click()">Open from File...</button>
<input type="file" id="fileUpload" name="files" style="display:none" />

快速而简洁。

2017年4月20日的答案的重复。 - Leo

1

好的,非常简单的纯CSS方法可以创建您自定义的输入文件。

使用标签,但是如您从之前的答案中了解的那样,标签在Firefox中不会调用onclick函数,可能是一个bug,但以下方法并不影响。

<label for="file"  class="custom-file-input"><input type="file"  name="file" class="custom-file-input"></input></label>

你需要做的是样式化标签,使其看起来符合你的要求。
    .custom-file-input {
        color: transparent;/* This is to take away the browser text for file uploading*/
        /* Carry on with the style you want */
        background: url(../img/doc-o.png);
        background-size: 100%;
        position: absolute;
        width: 200px;
        height: 200px;
        cursor: pointer;
        top: 10%;
        right: 15%;
    }

现在只需隐藏实际的输入按钮,但不能将其设置为visability: hidden

因此,通过设置opacity: 0;来使其不可见。

input.custom-file-input {
    opacity: 0;
    position: absolute;/*set position to be exactly over your input*/
    left: 0;
    top: 0;
}

现在你可能已经注意到了,我在标签和输入框上使用了相同的类,这是因为我希望它们都具有相同的样式,在标签上任何位置点击实际上都是在点击不可见的输入框。


1
以下是一个样式化的上传按钮示例,它将读取图像,压缩它,并下载结果图像。它通过隐藏实际的输入元素来工作,然后通过一些诡计使得当您单击我们的虚假文件上传器时,它使用实际的输入元素弹出选择文件的窗口。通过使用此方法,我们可以完全控制文件上传器的外观,因为我们使用自己的元素而不是样式化文件上传菜单。如果我们将来想要添加拖放功能,这也使得添加变得容易。

接着我实际上创建了一系列关于这个文件上传按钮的博客文章

'use strict'
  
var AMOUNT = 10
var WIDTH = 600
var HEIGHT = 400
var canvas = document.getElementById('canvas')
canvas.width = WIDTH
canvas.height = HEIGHT

//here's how I created the clickable area
//user clicks the clickable area > we send a click event
//to the file opener > the file opener clicks on the open
//file button > the open file dialogue pops up

function clickableAreaListener(e){
  let clickEvent = new CustomEvent("click",{"from":"fileOpenerHandler"});
  document.getElementById("fileOpener").dispatchEvent(clickEvent);
}
function fileOpenerListener(e) {
  document.getElementById("file-btn").click();
  e.preventDefault();
}

function fileSelectedListener(e){
    readFiles(e.target.files);
}

document.getElementById('file-btn').addEventListener('change', fileSelectedListener);
document.getElementById("clickable-area").addEventListener('click', clickableAreaListener);
document.getElementById("fileOpener").addEventListener("click", fileOpenerListener);

function readFiles(files){
  files = [].slice.call(files); //turning files into a normal array

  for (var file of files){
    var reader = new FileReader();

    reader.onload = createOnLoadHandler(file);
    reader.onerror = fileErrorHandler;
    //there are also reader.onloadstart, reader.onprogress, and reader.onloadend handlers

    reader.readAsDataURL(file);
  }
}
  
function fileErrorHandler(e) {
  switch(e.target.error.code) {
    case e.target.error.NOT_FOUND_ERR:
      throw 'Image not found';
      break;
    case e.target.error.NOT_READABLE_ERR:
      throw 'Image is not readable';
      break;
    case e.target.error.ABORT_ERR:
      break;
    default:
      throw 'An error occurred while reading the Image';
  };
}

function createOnLoadHandler(file){
  console.log('reading ' + file.name + ' of type ' + file.type) //file.type will be either image/jpeg or image/png
  
  function onLoad(e){
    var data = e.target.result
    display(data);
    var compressedData = compressCanvas(AMOUNT)
    download(compressedData)
  }
  
  return onLoad
}
  
function display(data){
  
    var img = document.createElement('img');
    img.src = data;
  
    var context = canvas.getContext('2d')
    context.clearRect(0, 0, WIDTH, HEIGHT);
    context.drawImage(img, 0, 0, WIDTH, HEIGHT);
  }

function compressCanvas(){
    return canvas.toDataURL('image/jpeg', AMOUNT / 100);
  }

function download(data) {

    function b64toBlob(b64Data, contentType, sliceSize) {
        contentType = contentType || '';
        sliceSize = sliceSize || 512;

        var byteCharacters = atob(b64Data);
        var byteArrays = [];

        for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            var slice = byteCharacters.slice(offset, offset + sliceSize);

            var byteNumbers = new Array(slice.length);
            for (var i = 0; i < slice.length; i++) {
                byteNumbers[i] = slice.charCodeAt(i);
            }

            var byteArray = new Uint8Array(byteNumbers);

            byteArrays.push(byteArray);
        }

        var blob = new Blob(byteArrays, {type: contentType});
        return blob;
    }
    
    var chromeApp = Boolean(chrome && chrome.permissions)
    if (chromeApp){
    
      chrome.fileSystem.chooseEntry({type:'openDirectory'}, function(entry) {
        chrome.fileSystem.getWritableEntry(entry, function(entry) {
          entry.getFile('example.jpg', {create:true}, function(entry) {
            entry.createWriter(function(writer){
              writer.write(b64toBlob(data.slice(23), 'image/jpg'))
            })
          })
        })
      })
    
    } else {
      let a = document.createElement("a");
      a.href = data;
      a.download = 'downloadExample.jpg'
      document.body.appendChild(a)
      a.click();
      window.URL.revokeObjectURL(a.href);
      a.remove()
  }
    
}
.fileInput {
  display: none;
  position: absolute;
  top: 0;
  right: 0;
  font-size: 100px;
}
  
#clickable-area{
  background: #ccc;
  width: 500px;
  display: flex;
  margin-bottom: 50px;
}
  
#clickable-area-text{
  margin: auto;
}

.yellow-button {
  cursor: pointer;
  color: white;
  background: #f1c40f;
  height: 30px;
  width: 120px;
  padding: 30px;
  font-size: 22px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
<div id="clickable-area">
  <a id='fileOpener'> </a>
  <input type="file" class="fileInput" id="file-btn" accept="image/*" multiple/>
  <div class="yellow-button"><span>Shrink Image</span>
  </div><p id="clickable-area-text">( you can click anywhere in here ) &nbsp;</p>
</div>
  
<canvas id="canvas"></canvas>

Stack Overflow的限制似乎阻止了代码片段实际压缩和下载文件。这里完全相同的代码表明完整的上传/压缩/下载过程确实按预期工作。


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