在JavaScript中,我可以以编程方式为文件输入元素触发“单击”事件吗?

时间:2008-10-16 23:30:36

标签: javascript html

我想以编程方式在<input type="file">标记上触发点击事件。

只是调用click()似乎没有做任何事情,或者至少它没有弹出文件选择对话框。

我一直在尝试使用侦听器捕获事件并重定向事件,但我无法像点击某个人那样实际执行事件。

29 个答案:

答案 0 :(得分:258)

我一直在寻找解决方案。这些是我的结论:

  1. 出于安全原因,Opera和Firefox不允许触发文件输入。
  2. 唯一方便的选择是创建一个“隐藏”文件输入(使用不透明度,而不是“隐藏”或“显示:无”!)然后创建“下方”按钮。通过这种方式可以看到按钮,但在用户点击时,它实际上会激活文件输入。
  3. 希望这有帮助! :)

    <div style="display: block; width: 100px; height: 20px; overflow: hidden;">
    <button style="width: 110px; height: 30px; position: relative; top: -5px; left: -5px;"><a href="javascript: void(0)">Upload File</a></button>
    <input type="file" id="upload_input" name="upload" style="font-size: 50px; width: 120px; opacity: 0; filter:alpha(opacity=0);  position: relative; top: -40px;; left: -20px" />
    </div>
    

答案 1 :(得分:76)

你不能在所有浏览器中都这样做,据说IE 允许它,但Mozilla和Opera不这样做。

当你在GMail中撰写邮件时,“附加文件”功能是以IE的方式和任何支持它的浏览器实现的,然后为Firefox和那些不支持的浏览器实现另一种方式。

我不知道为什么你不能这样做,但是 存在安全风险,而且你不允许在任何浏览器中做的一件事,是以编程方式设置文件名。 HTML文件元素。

答案 2 :(得分:66)

您可以在任何浏览器上触发click(),但某些浏览器需要该元素可见且专注。这是一个jQuery示例:

$('#input_element').show();
$('#input_element').focus();
$('#input_element').click();
$('#input_element').hide();

它适用于click()之前的隐藏,但我不知道它是否可以在不调用show方法的情况下运行。从来没有在Opera上试过这个,我在IE / FF / Safari / Chrome上测试过它的确有效。我希望这会有所帮助。

答案 3 :(得分:27)

这是可能的: 在FF4 +,Opera ?, Chrome下: 但是:

    应该从用户操作上下文中调用
  1. inputElement.click()! (不是脚本执行上下文)

  2. <input type="file" />应该是可见的(inputElement.style.display !== 'none')(您可以通过可见性或其他内容隐藏它,但不能隐藏“显示”属性)

答案 4 :(得分:10)

对于那些了解你必须在链接上叠加一个不可见形式但又懒得写的人,我会为你写的。好吧,对我而言,不妨分享一下。欢迎提出意见。

HTML(某处):

<a id="fileLink" href="javascript:fileBrowse();" onmouseover="fileMove();">File Browse</a>

HTML(你不关心的地方):

<div id="uploadForm" style="filter:alpha(opacity=0); opacity: 0.0; width: 300px; cursor: pointer;">
    <form method="POST" enctype="multipart/form-data">
        <input type="file" name="file" />
    </form>
</div>

JavaScript的:

function pageY(el) {
    var ot = 0;
    while (el && el.offsetParent != el) {
        ot += el.offsetTop ? el.offsetTop : 0;
        el = el.offsetParent;
    }
    return ot;
}

function pageX(el) {
    var ol = 0;
    while (el && el.offsetParent != el) {
        ol += el.offsetLeft ? el.offsetLeft : 0;
        el = el.offsetParent;
    }
    return ol;
}

function fileMove() {
    if (navigator.appName == "Microsoft Internet Explorer") {
        return; // Don't need to do this in IE. 
    }
    var link = document.getElementById("fileLink");
    var form = document.getElementById("uploadForm");
    var x = pageX(link);
    var y = pageY(link);
    form.style.position = 'absolute';
    form.style.left = x + 'px';
    form.style.top = y + 'px';
}

function fileBrowse() {
    // This works in IE only. Doesn't do jack in FF. :( 
    var browseField = document.getElementById("uploadForm").file;
    browseField.click();
}

答案 5 :(得分:9)

答案 6 :(得分:7)

如果您希望click方法适用于Chrome,Firefox等,请将以下样式应用于输入文件。它将被完全隐藏,就像你做display: none;

一样
#fileInput {
    visibility: hidden;
    position: absolute;
    top: 0;
    left: -5000px;
}

就这么简单,我测试它有效!

答案 7 :(得分:5)

$(document).one('mousemove', function() { $(element).trigger('click') } );

当我遇到类似问题时为我工作,这是一个普通的eRube Goldberg。

答案 8 :(得分:5)

只需使用标签标签,这样您就可以隐藏输入,并使其通过相关标签工作 https://developer.mozilla.org/fr/docs/Web/HTML/Element/Label

答案 9 :(得分:4)

有效:

出于安全原因,在Firefox和Opera上,您无法触发文件输入上的点击,但您可以使用MouseEvents进行模拟:

<script>
click=function(element){
    if(element!=null){
        try {element.click();}
        catch(e) {
            var evt = document.createEvent("MouseEvents");
            evt.initMouseEvent("click",true,true,window,0,0,0,0,0,false,false,false,false,0,null);
            element.dispatchEvent(evt);
            }
        }
    };
</script>

<input type="button" value="upload" onclick="click(document.getElementById('inputFile'));"><input type="file" id="inputFile" style="display:none">

答案 10 :(得分:3)

JS小提琴:http://jsfiddle.net/eyedean/1bw357kw/

&#13;
&#13;
popFileSelector = function() {
    var el = document.getElementById("fileElem");
    if (el) {
        el.click();  
    }
};

window.popRightAway = function() {
    document.getElementById('log').innerHTML += 'I am right away!<br />';
    popFileSelector();
};

window.popWithDelay = function() {
    document.getElementById('log').innerHTML += 'I am gonna delay!<br />';
    window.setTimeout(function() {
        document.getElementById('log').innerHTML += 'I was delayed!<br />';
        popFileSelector();
    }, 1000);
};
&#13;
<body>
  <form>
      <input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)" />
  </form>
  <a onclick="popRightAway()" href="#">Pop Now</a>
    <br />
  <a onclick="popWithDelay()" href="#">Pop With 1 Second Delay</a>
    <div id="log">Log: <br /></div>
</body>
&#13;
&#13;
&#13;

答案 11 :(得分:3)

此代码适用于我。这是你想要做的吗?

<input type="file" style="position:absolute;left:-999px;" id="fileinput" />
<button  id="addfiles" >Add files</button>

<script language="javascript" type="text/javascript">
   $("#addfiles").click(function(){
      $("#fileinput").click();
   });
</script>

答案 12 :(得分:3)

以下是此问题的纯JavaScript解决方案。适用于所有浏览器

<script>
    function upload_image_init(){
        var elem = document.getElementById('file');
        if(elem && document.createEvent) {
           var evt = document.createEvent("MouseEvents");
           evt.initEvent("click", true, false);
           elem.dispatchEvent(evt);
        }
    }
</script>

答案 13 :(得分:3)

我使用jQuery和jQuery-ui的Safari解决方案:

$("<input type='file' class='ui-helper-hidden-accessible' />").appendTo("body").focus().trigger('click');

答案 14 :(得分:3)

  

工作解决方案

让我添加到这篇旧帖子中,我过去使用的工作解决方案可能适用于所有新老浏览器的80%或更多。

解决方案既复杂又简单。第一步是利用CSS并使用“under-elements”来表示输入文件类型,因为它的不透明度为0.显示通过。下一步是使用JavaScript根据需要更新其标签。

  

HTML 如果您想快速访问特定元素,则只需插入ID,但这些类必须与设置此类的CSS相关整个过程

<div class="file-input wrapper">
    <input id="inpFile0" type="file" class="file-input control" />
    <div class="file-input content">
        <label id="inpFileOutput0" for="inpFileButton" class="file-input output">Click Here</label>
        <input id="inpFileButton0" type="button" class="file-input button" value="Select File" />
    </div>
</div>
  

CSS 请记住,着色和字体样式等完全是您的首选,如果您使用这个基本的CSS,您可以随时使用后端标记来设置样式,这是显示在最后列出的jsFiddle中。

.file-test-area {
    border: 1px solid;
    margin: .5em;
    padding: 1em;
}
.file-input {
    cursor: pointer !important;
}
.file-input * {
    cursor: pointer !important;
    display: inline-block;
}
.file-input.wrapper {
    display: inline-block;
    font-size: 14px;
    height: auto;
    overflow: hidden;
    position: relative;
    width: auto;
}
.file-input.control {
    -moz-opacity:0 ;
    filter:alpha(opacity: 0);
    opacity: 0;

    height: 100%;
    position: absolute;
    text-align: right;
    width: 100%;
    z-index: 2;
}
.file-input.content {
    position: relative;
    top: 0px;
    left: 0px;
    z-index: 1;
}
.file-input.output {
    background-color: #FFC;
    font-size: .8em;
    padding: .2em .2em .2em .4em;
    text-align: center;
    width: 10em;
}
.file-input.button {
    border: none;
    font-weight: bold;
    margin-left: .25em;
    padding: 0 .25em;
}
  

JavaScript 纯粹而真实,但是,某些OLDER(已淘汰的)浏览器仍可能遇到问题(如Netscrape 2!) < / p>

var inp = document.getElementsByTagName('input');
for (var i=0;i<inp.length;i++) {
    if (inp[i].type != 'file') continue;
    inp[i].relatedElement = inp[i].parentNode.getElementsByTagName('label')[0];
    inp[i].onchange /*= inp[i].onmouseout*/ = function () {
        this.relatedElement.innerHTML = this.value;
    };
};

Working jsFiddle Example

答案 15 :(得分:3)

我知道这已经过时了,所有这些解决方案都是针对具有真正价值的浏览器安全预防措施。

也就是说,截至今天,fileInput.click()适用于当前的Chrome(36.0.1985.125 m)和当前的Firefox ESR(24.7.0),但不适用于当前的IE(11.0.9600.17207)。在按钮顶部覆盖具有不透明度0的文件字段,但我希望链接元素作为可见触发器,并且悬停下划线在任何浏览器中都不起作用。它闪烁然后消失,浏览器可能会考虑悬停样式是否真的适用。

但我确实找到了适用于所有浏览器的解决方案。我不是声称已经测试了每个浏览器的每个版本,或者我知道它会继续工作,但它现在似乎满足了我的需求。

这很简单:将文件输入字段放在屏幕外(位置:绝对;顶部:-5000px),在其周围放置一个标签元素,然后触发标签上的点击,而不是文件字段本身。 / p>

请注意,链接确实需要编写脚本来调用标签的click方法,它不会自动执行此操作,就像单击label元素中的文本一样。显然,链接元素会捕获点击,但它并没有通过标签。

另请注意,这并未提供显示当前所选文件的方法,因为该字段位于屏幕外。我想在选择文件时立即提交,这对我来说不是问题,但如果你的情况不同,你需要采用一种不同的方法。

答案 16 :(得分:2)

嘿,这个解决方案有效。 下载我们应该使用MSBLOB

$scope.getSingleInvoicePDF = function(invoiceNumberEntity) {
   var fileName = invoiceNumberEntity + ".pdf";
   var pdfDownload = document.createElement("a");
   document.body.appendChild(pdfDownload);

   AngularWebService.getFileWithSuffix("ezbillpdfget",invoiceNumberEntity,"pdf" ).then(function(returnedJSON) {
       var fileBlob = new Blob([returnedJSON.data], {type: 'application/pdf'});
       if (navigator.appVersion.toString().indexOf('.NET') > 0) { // for IE browser
           window.navigator.msSaveBlob(fileBlob, fileName);
       } else { // for other browsers
           var fileURL = window.URL.createObjectURL(fileBlob);
           pdfDownload.href = fileURL;
           pdfDownload.download = fileName;
           pdfDownload.click();      
       }
   });
};

对于AngularJS甚至是普通的javascript。

答案 17 :(得分:2)

有一些方法可以将事件重定向到控件,但是不希望自己能够轻松地将事件发送到fire控件,因为浏览器会出于(良好的)安全原因试图阻止它。

如果您只需要在用户点击某些内容时显示文件对话框,那么就说因为您需要更好看的文件上传按钮,那么您可能需要查看what Shaun Inman came up with

我已经能够通过创造性地将焦点转移到keydown,keypress和amp;之间的控制中来实现键盘触发。 keyup事件。 YMMV。

我真诚的建议是让这一切独处,因为这是一个浏览器不兼容的世界 - 痛苦。次要浏览器更新也可能会在没有警告的情况下阻止技巧,您可能必须不断重新发明黑客以保持其正常工作。

答案 18 :(得分:2)

我在视图中隐藏了<input type="button">标记。我所做的是将"onClick"事件附加到任何类型的任何可见组件,例如标签。这是使用Google Chrome的开发人员工具或Mozilla Firefox的Firebug使用右键单击“编辑HTML”命令完成的。在此事件中,请指定以下脚本或类似内容:

如果你有JQuery:

$('#id_of_component').click();

如果不是:

document.getElementById('id_of_component').click();

感谢。

答案 19 :(得分:2)

我刚刚研究过这个,因为我想创建一个自定义按钮,打开文件对话框并立即开始上传。我刚刚注意到可能使这成为可能的东西 - 当你点击上传的任何地方时,firefox似乎打开了对话框。所以以下可能会这样做:

  1. 创建文件上传和包含要用作按钮的图像的单独元素
  2. 安排它们重叠并使文件元素背景和边框透明,以便按钮是唯一可见的
  3. 添加javascript以使IE在单击按钮/文件输入时打开对话框
  4. 使用onchange事件在选择文件时提交表单
  5. 这只是理论上的,因为我已经使用了另一种方法来解决问题,但它可能会起作用。

答案 20 :(得分:1)

希望这对某人有所帮助 - 我花了2个小时撞击它:

在IE8或IE9中,如果你以任何方式触发用javascript打开文件输入(相信我已经尝试过所有这些),它不会让你使用javascript提交表单,它会默默地失败

通过常规提交按钮提交表单可能有效,但调用form.submit();将默默地失败。

我不得不求助于使用透明文件输入覆盖我的选择文件按钮。

答案 21 :(得分:1)

我发现如果输入(文件)是外部表单,则触发click事件会调用文件对话框。

答案 22 :(得分:1)

这对我有用:

<script>
    function sel_file() {
        $("input[name=userfile]").trigger('click');
    }  
</script>

<input type="file" name="userfile" id="userfile" />

<a href="javascript:sel_file();">Click</a>

答案 23 :(得分:1)

您可以根据Open File Dialog box on <a> tag

的回答执行此操作
<input type="file" id="upload" name="upload" style="visibility: hidden; width: 1px;     height: 1px" multiple />
<a href="" onclick="document.getElementById('upload').click(); return false">Upload</a>

答案 24 :(得分:1)

这是适用于我的解决方案: 的 CSS:

#uploadtruefield {
    left: 225px;
    opacity: 0;
    position: absolute;
    right: 0;
    top: 266px;
    opacity:0;
    -moz-opacity:0;
    filter:alpha(opacity:0);
    width: 270px;
    z-index: 2;
}

.uploadmask {
    background:url(../img/browse.gif) no-repeat 100% 50%;
}
#uploadmaskfield{
    width:132px;
}

带有“小”JQuery帮助的HTML:

<div class="uploadmask">
    <input id="uploadmaskfield" type="text" name="uploadmaskfield">
</div>
<input id="uploadtruefield"  type="file" onchange="$('#uploadmaskfield').val(this.value)" >

请确保通过真正的上传字段完全覆盖了掩码。

答案 25 :(得分:1)

这不是不可能的:

var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);  
setTimeout(function(){ document.getElementById('input_field_id').dispatchEvent(evObj); },100);

但不知何故,只有在通过点击事件调用的函数中它才有效。

所以你可能有以下设置:

HTML:

<div onclick="openFileChooser()" class="some_fancy_stuff">Click here to open image chooser</div>
<input type="file" id="input_img">

JavaScript的:

    function openFileChooser() {
      var evObj = document.createEvent('MouseEvents');
      evObj.initMouseEvent('click', true, true, window);  
      setTimeout(function()
      { 
        document.getElementById('input_img').dispatchEvent(evObj);      
      },100);      
    }

答案 26 :(得分:1)

现在可以在Firefox 4中使用,但需要注意的是它会被视为一个弹出窗口,因此每当弹出窗口出现时都会被阻止。

答案 27 :(得分:0)

您可以使用

<button id="file">select file</button>
<input type="file" name="file" id="file_input" style="display:none;">
<script>
$('#file').click(function() {
        $('#file_input').focus().trigger('click');
    });
</script>

答案 28 :(得分:0)

为此,您可以单击文件输入上的一个不可见的传递元素:

function simulateFileClick() {
  const div = document.createElement("div")
  div.style.visibility = "hidden"
  div.style.position = "absolute"
  div.style.width = "100%"
  div.style.height = "100%"
  div.style.pointerEvents = "none"
  const fileInput = document.getElementById("fileInput") // or whatever selector you like
  fileInput.style.position = "relative"
  fileInput.appendChild(div)
  const mouseEvent = new MouseEvent("click")
  div.dispatchEvent(mouseEvent)
}