88
$('#id').click();

它不适用于 Mac OS 上的 Chrome 26。

问题实际上是创建可以集成在表单中的“上传”小部件。小部件将由两部分组成。第一部分是带有启动器按钮和错误/成功消息的 div。我认为方法是将另一个表单作为文件输入的第二部分并将文件提交到 iframe。提交后,我们在主表单的第一部分填写隐藏字段或显示错误。

简单的方法是将文件表单添加到主表单中,但这是被禁止的。

4

10 回答 10

177

使用 jQuery

我会创建一个按钮和一个不可见的输入,如下所示:

<button id="button">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />

并添加一些 jQuery 来触发它:

$('#button').on('click', function() {
    $('#file-input').trigger('click');
});

使用香草 JS

同样的想法,没有 jQuery(归功于@Pascale):

<button onclick="document.getElementById('file-input').click();">Open</button>
<input id="file-input" type="file" name="name" style="display: none;" />
于 2013-04-25T13:22:40.230 回答
167

仅 JS - 不需要 jquery

只需创建一个输入元素并触发点击。

var input = document.createElement('input');
input.type = 'file';
input.click();

这是最基本的,弹出一个选择文件对话框,但如果不处理所选文件,它就没有任何用处......

处理文件

向新创建的输入添加onchange事件将允许我们在用户选择文件后执行操作。

var input = document.createElement('input');
input.type = 'file';

input.onchange = e => { 
   var file = e.target.files[0]; 
}

input.click();

目前我们有存储各种信息的文件变量:

file.name // the file's name including extension
file.size // the size in bytes
file.type // file type ex. 'application/pdf'

伟大的!

但是,如果我们需要文件的内容怎么办?

为了得到文件的实际内容,出于各种原因。放置图像,加载到画布中,使用 Base64 数据 url 创建一个窗口等。我们需要使用FileReaderAPI

我们将创建 FileReader 的一个实例,并将我们用户选择的文件引用加载到它。

var input = document.createElement('input');
input.type = 'file';

input.onchange = e => { 

   // getting a hold of the file reference
   var file = e.target.files[0]; 

   // setting up the reader
   var reader = new FileReader();
   reader.readAsText(file,'UTF-8');

   // here we tell the reader what to do when it's done reading...
   reader.onload = readerEvent => {
      var content = readerEvent.target.result; // this is the content!
      console.log( content );
   }

}

input.click();

尝试将上述代码粘贴到您的开发工具的控制台窗口中,它应该会产生一个选择文件对话框,选择文件后,控制台现在应该打印文件的内容。

示例 - “Stackoverflow 的新背景图片!”

让我们尝试创建一个文件选择对话框来将 stackoverflows 背景图像更改为更辣的东西......

var input = document.createElement('input');
input.type = 'file';

input.onchange = e => { 

   // getting a hold of the file reference
   var file = e.target.files[0]; 

   // setting up the reader
   var reader = new FileReader();
   reader.readAsDataURL(file); // this is reading as data url

   // here we tell the reader what to do when it's done reading...
   reader.onload = readerEvent => {
      var content = readerEvent.target.result; // this is the content!
      document.querySelector('#content').style.backgroundImage = 'url('+ content +')';
   }

}

input.click();

打开 devtools,并将上面的代码粘贴到控制台窗口,这应该会弹出一个选择文件对话框,选择图像后,stackoverflows 内容框背景应该会更改为所选图像。

干杯!

于 2016-12-05T10:18:05.350 回答
19

即用型功能(使用 Promise)

/**
 * Select file(s).
 * @param {String} contentType The content type of files you wish to select. For instance, use "image/*" to select all types of images.
 * @param {Boolean} multiple Indicates if the user can select multiple files.
 * @returns {Promise<File|File[]>} A promise of a file or array of files in case the multiple parameter is true.
 */
function selectFile(contentType, multiple){
    return new Promise(resolve => {
        let input = document.createElement('input');
        input.type = 'file';
        input.multiple = multiple;
        input.accept = contentType;

        input.onchange = () => {
            let files = Array.from(input.files);
            if (multiple)
                resolve(files);
            else
                resolve(files[0]);
        };

        input.click();
    });
}

在这里试试

// Content wrapper element
let contentElement = document.getElementById("content");

// Button callback
async function onButtonClicked(){
    let files = await selectFile("image/*", true);
    contentElement.innerHTML = files.map(file => `<img src="${URL.createObjectURL(file)}" style="width: 100px; height: 100px;">`).join('');
}

// ---- function definition ----
function selectFile (contentType, multiple){
    return new Promise(resolve => {
        let input = document.createElement('input');
        input.type = 'file';
        input.multiple = multiple;
        input.accept = contentType;

        input.onchange = _ => {
            let files = Array.from(input.files);
            if (multiple)
                resolve(files);
            else
                resolve(files[0]);
        };

        input.click();
    });
}
<button onclick="onButtonClicked()">Select images</button>
<div id="content"></div>

于 2018-10-11T10:13:42.577 回答
13

为了完整起见,Ron van der Heijden在纯 JavaScript 中的解决方案:

<button onclick="document.querySelector('.inputFile').click();">Select File ...</button>
<input class="inputFile" type="file" style="display: none;">
于 2016-11-14T21:07:04.147 回答
11

仅在 HTML 中:

<label>
  <input type="file" name="input-name" style="display: none;" />
  <span>Select file</span>
</label>

编辑:我没有在 Blink 中测试过这个,它实际上不适用于 a <button>,但它应该适用于大多数其他元素——至少在最近的浏览器中。

用上面的代码检查这个小提琴。

于 2015-03-17T12:36:59.473 回答
8

要扩展“levi”的答案并展示如何从上传中获取响应,以便您可以处理文件上传:

selectFile(event) {
    event.preventDefault();

    file_input = document.createElement('input');
    file_input.addEventListener("change", uploadFile, false);
    file_input.type = 'file';
    file_input.click();
},

uploadFile() {
    let dataArray = new FormData();
    dataArray.append('file', file_input.files[0]);

    // Obviously, you can substitute with JQuery or whatever
    axios.post('/your_super_special_url', dataArray).then(function() {
        //
    });
}
于 2018-05-06T12:13:44.953 回答
5

function promptFile(contentType, multiple) {
  var input = document.createElement("input");
  input.type = "file";
  input.multiple = multiple;
  input.accept = contentType;
  return new Promise(function(resolve) {
    document.activeElement.onfocus = function() {
      document.activeElement.onfocus = null;
      setTimeout(resolve, 500);
    };
    input.onchange = function() {
      var files = Array.from(input.files);
      if (multiple)
        return resolve(files);
      resolve(files[0]);
    };
    input.click();
  });
}
function promptFilename() {
  promptFile().then(function(file) {
    document.querySelector("span").innerText = file && file.name || "no file selected";
  });
}
<button onclick="promptFilename()">Open</button>
<span></span>

于 2020-07-09T15:21:38.137 回答
1

首先声明一个变量来存储文件名(稍后使用它们):

var myfiles = [];

打开文件对话框

$('#browseBtn').click(function() {
    $('<input type="file" multiple>').on('change', function () {
        myfiles = this.files; //save selected files to the array
        console.log(myfiles); //show them on console
    }).click();
});

我正在发布它,所以它可能会对某人有所帮助,因为互联网上没有关于如何将文件名存储到数组中的明确说明!

于 2018-12-17T18:26:51.497 回答
0

使用 jquery 库

<button onclick="$('.inputFile').click();">Select File ...</button>
<input class="inputFile" type="file" style="display: none;">
于 2020-04-20T23:53:52.533 回答
0

这个问题让我很困惑。添加 addeventlistener 调用了我不想要的事件。如果您对简单的选择器感兴趣,则不需要事件。输入/文件对话框将从单独的窗口返回到具有所选文件名的调用者(如果您查看调试器中的元素,“文件”对象还带有一些其他属性。感谢 user4602228 指路...

如下所示的简单输入/输出文件选择器 >>>

function loadsettings()
//
// use web page dialog to get user settings file
//
{
   var setload=parent.settings.document.createElement("input");
   setload.type="file";
   setload.click();
   settings(*setload.files[0]*,false,false); //these are custom parameters 
}
return;
于 2022-03-04T22:42:02.970 回答