JavaScript 中的打开文件对话框

Posted

技术标签:

【中文标题】JavaScript 中的打开文件对话框【英文标题】:Open file dialog box in JavaScript 【发布时间】:2011-01-04 02:49:00 【问题描述】:

我需要一种解决方案,以便在单击 div 时以 html 格式显示打开的文件对话框。单击div 时必须打开打开文件对话框。

我不想将输入文件框显示为 HTML 页面的一部分。它必须显示在单独的对话框中,而不是网页的一部分。

【问题讨论】:

警报不是文件对话框? - 你能澄清你在问什么吗? 我认为他是说他想要标准的“打开文件”弹出窗口 点击 div 时我需要打开文件对话框。它必须像不属于网页的警报一样 【参考方案1】:

AFAIK 你仍然需要一个<input type="file"> 元素,然后你可以使用quirksmode 中的一些东西来设置它的样式

【讨论】:

【参考方案2】:

这个不错

Fine Uploader demo

它本身就是一个<input type='file' /> 控件。但是在其上放置了一个 div,并应用了 css 样式来获得这种感觉。文件控件的不透明度设置为 0,以便在单击 div 时看起来对话窗口已打开。

【讨论】:

有没有办法通过 javascript 来控制显示的文件...说我想打开文件对话框,只想显示带有 .pdf 的文件扩展名.. @Ajax3.14 新浏览器具有 FileReader 对象,旧浏览器您必须使用该值并查找文件扩展名。 @Ajax3.14 无需使用 FileReader 或解析扩展。许多浏览器支持文件输入的接受属性。这允许您限制文件浏览器对话框中显示的文件类型。 Fine Uploader 通过验证选项的 acceptFiles 属性提供对此功能的访问。有关详细信息,请参阅validation section of the options documentation。请注意,IE9 或更早版本不支持 accept 属性。 怎么这么好?这是一个好习惯吗?不应该是这样的:***.com/a/18659941/915865? @KatLimRuiz 不,您链接到的答案不是一个好的解决方案。如果您最终也以编程方式提交关联的表单,这将导致 IE 抛出错误。【参考方案3】:

唯一没有<input type="file"> 的是在div 上嵌入一个透明的flash 电影。然后,您可以使用用户生成的点击事件(符合 Flash 10 新安全规则)来触发对 flash 的FileReference.browse 的调用。

它提供了对quirksmode way 的额外依赖,但作为回报,您会获得更多事件(例如内置的进程事件)。

【讨论】:

11 年多之后,我可以说 这将不再有效。 ?【参考方案4】:

    $("#logo").css('opacity','0');
    
    $("#select_logo").click(function(e)
       e.preventDefault();
       $("#logo").trigger('click');
    );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#" id="select_logo">Select Logo</a> <input type="file" id="logo">

对于 IE 添加这个:

$("#logo").css('filter','alpha(opacity = 0');

【讨论】:

为什么在#select_logo 点击处理程序中返回false? 它不会产生 404 错误,它只会尝试导航到当前页面,并在末尾添加 #。这将使页面跳转到顶部。所以很高兴在那里,只是出于不同的原因:) 虽然我测试得还不够,“可见性:隐藏;”似乎更兼容。此外,尽管 opacity: 0 单击“不可见”元素时会触发单击事件,而 visibility: hidden 不会。 MDN表示document.getElementById("logo").click()就够了。他们还展示了另一种方式“拖放”。 developer.mozilla.org/en-US/docs/Web/API/File/… 你应该把它转换成普通的 Javascript,JQuery 不适合在这么小的项目上使用 ^_^【参考方案5】:

首先添加head标签:

<script>
   function showDialog(openFileDialog) 
       document.getElementById(openFileDialog).click();
   
   function fileName(openFileDialog) 
       return document.getElementById(openFileDialog).value;
   
   function hasFile(openFileDialog) 
       return document.getElementById(openFileDialog).value != "";
   
   function fileNameWithoutFakePath(openFileDialog) 
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(fileName.lastIndexOf('\\') + 1);
   
   function fakePathWithoutFileName(openFileDialog) 
       var fileName = document.getElementById(openFileDialog).value;
       return fileName.substr(0, fileName.lastIndexOf('\\'));
   
</script>

如果你已经有 script 标签,只需在上面添加这些函数即可。

在您的 bodyform 标签中添加:

<input type="file" style="display:none" id="yourDesiredOrFavoriteNameForTheNewOpenFileDialogInstance"/>

无论在您的 html 中的哪个位置,只是 像那样 您已经创建了一个类型为 OpenFileDialog 类的新实例作为 global 变量,其名称为 元素的id,无论在你的代码或xaml中,在你的脚本或代码中,你不能输入他的名字,然后阅读属性或调用函数,因为有全局函数执行元素输入类型 =“文件”中未定义的那些。您只需为这些函数提供隐藏输入 type="file" 的 id,它是 OpenFileDialog 实例的名称作为字符串。

为了让您轻松地为 html 创建打开文件对话框实例,您可以创建一个函数来完成它:

function createAndAddNewOpenFileDialog(name) 
     document.getElementById("yourBodyOrFormId").innerHtml += "<input type='file' style='display:none' id='" + name + "'/>"

如果你想删除打开文件对话框,那么你可以制作并使用以下函数:

function removeOpenFileDialog(name) 
    var html = document.getElementById("yourBodyOrFormId").innerHtml;
    html = html.replace("<input type='file' style='display:none' id='" + name + "'/>", "");
    document.getElementById("yourBodyOrFormId").innerHtml = html;

但在删除打开文件对话框之前,请通过制作和使用以下函数确保它存在:

function doesOpenFileDialogExist(name) 
    return document.getElementById("yourBodyOrFormId").innerHtml.indexOf("<input type='file' style='display:none' id='" + name + "'/>") != -1

如果您不想在 html 的 bodyform 标记中创建和添加打开文件对话框,因为这是添加隐藏输入 type= “文件”,然后你可以使用上面的创建函数在脚本中完成:

function yourBodyOrFormId_onload() 
    createAndAddNewOpenFileDialog("openFileDialog1");
    createAndAddNewOpenFileDialog("openFileDialog2");
    createAndAddNewOpenFileDialog("openFileDialog3");
    createAndAddNewOpenFileDialog("File Upload");
    createAndAddNewOpenFileDialog("Image Upload");
    createAndAddNewOpenFileDialog("bla");
    //etc and rest of your code

确保在您的身体或表单标签附近添加了:

onload="yourBodyOrFormId_onload()"

如果您已经这样做了,则不必在上面执行此操作。

提示:如果您还没有,您可以将新的 JScript 文件添加到您的项目或网站中,并且在此文件中您可以将所有打开的文件对话框功能从 script 标签和 html 或 web 表单页面,并在此 JScript 文件中的 html 或 web 表单页面中使用它们,但不要忘记之前将 html 或 web 表单页面链接到 JScript 文件.您只需将 JScript 文件拖到 head 标记中的 html 页面即可。如果您的页面是 web 表单而不是简单的 html,并且您没有 head 标签,则将其放在任何地方以便它可以工作。 不要忘记在该 JScript 文件中定义全局变量,其值将是您的正文或表单 id 作为字符串。将 JScript 文件链接到 html 或 web 表单页面后,您可以 onload 表单正文的事件,将该变量的值设置为您的正文或表单 ID。然后在 JScript 文件中,您不必再为文档提供一页的正文或表单的 id,只需为其提供该变量的值即可。您可以将该变量命名为 bodyIdformIdbodyOrFormId 或您想要的任何其他名称。

祝你好运!

【讨论】:

最好不要直接修改innerHTML。【参考方案6】:

实际上,您不需要所有具有不透明度、可见性、&lt;input&gt; 样式等的东西。看看吧:

<a href="#">Just click me.</a>
<script type="text/javascript">
    $("a").click(function() 
        // creating input on-the-fly
        var input = $(document.createElement("input"));
        input.attr("type", "file");
        // add onchange handler if you wish to get the file :)
        input.trigger("click"); // opening dialog
        return false; // avoiding navigation
    );
</script>

jsFiddle 上的演示。在 Chrome 30.0 和 Firefox 24.0 中测试。但是,在 Opera 12.16 中不起作用。

【讨论】:

这应该是正确的答案。纯Javascript实现,无需修改任何HTML代码。 愚蠢的问题,但是之后您将如何获得选择的文件? 这是一个危险的解决方案,可能会导致意外问题。例如,如果文件输入也以编程方式打开,某些浏览器(如 IE)可能会阻止以编程方式提交表单。解决此问题的最佳方法是使用 CSS,而不是 JavaScript。 @Charleston 不幸的是,它在某些浏览器中不起作用。他们应该让它工作:) 截至 2020 年,此解决方案似乎是最好的。在 Edge、Safari、Opera、Firefox 和 Chrome 中的 BrowserStack 上对其进行了测试。适用于所有这些。【参考方案7】:

我不知道为什么没有人指出这一点,但这是一种无需任何 Javascript 的方式,它也与任何浏览器兼容。


编辑:在 Safari 中,input 在使用 display: none 隐藏时会被禁用。更好的方法是使用position: fixed; top: -100em

编辑 2:另一种方法是使用 opacity: 0。问题是它会弄乱布局。我在示例中添加了一些 CSS 来说明问题。


label 
    display: inline-block;
    background: #ddd;
    border: 1px outset #ccc;
    border-radius: .3em;
    padding: .3em 1em;
    margin: .5em;


label:active 
  border-style: inset;
<label>
  Using <code>position: fixed</code>
  <input type="file" style="position: fixed; top: -100%">
</label>

<label>
  Using <code>opacity: 0</code>
  <input type="file" style="opacity: 0">
</label>

如果您愿意,您可以通过在label 中使用for 指向输入的id 来采用“正确方式”,如下所示:

<label for="inputId">file dialog</label>
<input id="inputId" type="file" style="position: fixed; top: -100em">

【讨论】:

这很像魅力,但是,这里有一些建议: 1. &lt;input&gt; 标签应该有name 属性; 2.如果指定for属性,&lt;input&gt;文件标签将需要id Simplicity is the ultimate sophistication 太棒了!即使有背景图像或使标签收到点击 javascript 触发,它也能像魅力一样工作。谢谢! 顺便说一句,有人指出了这个解决方案的一个问题,在 Safari 中,用display: none 隐藏的输入被禁用。解决方法是使用不同的方法来隐藏输入。我会更新答案以反映这一点。 @JPdelaTorre 如果您使用 opacity: 0 代替隐藏输入会更好。【参考方案8】:

如果客户端机器上的 javascript 被关闭怎么办?对所有场景使用以下解决方案。你甚至不需要 javascript/jQuery。 :

HTML

<label for="fileInput"><img src="File_upload_Img"><label>
<input type="file" id="fileInput"></label>

CSS

#fileInputopacity:0  
body
    background:cadetblue;

解释:for="Your input Id"。 HTML 默认触发点击事件。所以它默认触发点击事件,不需要jQuery/javascript。如果它只是由 HTML 完成,为什么要使用 jQuery/jScript?而且您无法判断客户端是否禁用了 JS。即使 JS 关闭,您的功能也应该可以工作。

Working jsFiddle(你不需要JS,jquery)

【讨论】:

为什么是背景? 为什么不透明?为什么不显示:无;【参考方案9】:

这是最适合我的方法(在 IE8、FF、Chrome、Safari 上测试)。

#file-input 
  cursor: pointer;
  outline: none;
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  overflow: hidden;
  filter: alpha(opacity=0); /* IE < 9 */
  opacity: 0;

.input-label 
  cursor: pointer;
  position: relative;
  display: inline-block;
<label for="file-input" class="input-label">
  Click Me <!-- Replace with whatever text or icon you wish to use -->
  <input type="file" id="file-input">
</label>

解释: 我将文件输入直接放置在要单击的元素上方,因此任何单击都将落在它或其标签上(这会拉出上传对话框,就像您单击标签本身一样)。我在默认输入的按钮部分伸出标签侧面时遇到了一些问题,因此输入上的overflow: hidden 和标签上的display: inline-block 是必要的。

【讨论】:

最大化输入并将不透明度设置为零。效果很好!【参考方案10】:

最简单的方法:

#file-input 
  display: none;
<label for="file-input">
  <div>Click this div and select a file</div>
</label>
<input type="file" id="file-input"/>

重要的是,使用display: none 可确保隐藏文件输入不会占用任何位置(使用opacity: 0 会发生什么情况)。

【讨论】:

如此简单有效,我觉得这是最好的解决方案!【参考方案11】:

可以使用

$('<input type="file" />').click()

【讨论】:

在我的情况下,这会导致自动重定向到发生原始点击事件的同一页面 - 使整个页面重新加载并丢失之前在页面中输入的所有数据。【参考方案12】:
    将输入元素type="file" 放在页面上的任何位置并使用style="display:none" 将其隐藏。给输入元素一个id。例如id="myid"
<input type="file" style="display:none" id="myid"/>
    选择要用于打开文件对话框的任何 div、图像、按钮或任何元素,为其设置 onclick 属性,如下所示:
<a href="#" onclick="document.getElementById('myid').click()"/>

【讨论】:

这很好用。这是一个演示该方法的 JSFiddle:jsfiddle.net/0x4ydrzv 我是专门来这里的,因为我想用 JS 打开对话框。对我来说,你可以在输入元素上调用 click 并不明显。谢谢! 但是,如果用户实际上没有点击某些东西,它似乎不起作用。例如在控制台中调用 click 不起作用,在 onload 中调用 click 也不起作用。

以上是关于JavaScript 中的打开文件对话框的主要内容,如果未能解决你的问题,请参考以下文章

文件下载对话框何时打开? - HTML, Javascript

如何使用 javascript 打开文件/浏览对话框?

javaScript产生一个文件保存对话框

可以使用 Javascript 打开 PDF 文件的打印对话框吗?

JavaScript:上传文件

JavaScript:上传文件