在JavaScript中,我可以创建一个“点击”;事件触发为文件输入元素编程?

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

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

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

348858 次浏览

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

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

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

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

如果你只需要在用户点击某些东西时显示文件对话框,比如说因为你想要更好看的文件上传按钮,那么你可能想看看肖恩·英曼想出了什么

我已经能够实现键盘触发与创造性的转移焦点之间的控制键下,按键和放大器;按键弹起事件。YMMV。

我真诚的建议是不要去管它,因为这是一个浏览器不兼容的痛苦世界。轻微的浏览器更新也可能会在没有警告的情况下阻止一些技巧,你可能不得不不断地重新发明一些技巧来保持它的工作。

我正在研究这个不久前,因为我想创建一个自定义按钮,将打开文件对话框,并立即开始上传。我刚刚注意到一些可能使这成为可能的事情- firefox似乎打开对话框,当你点击上传的任何地方。所以下面的方法可以做到:

  1. 创建一个文件上传和一个单独的元素,其中包含您想要用作按钮的图像
  2. 安排它们重叠,并使文件元素背景和边框透明,这样按钮是唯一可见的东西
  3. 添加javascript使IE在点击按钮/文件输入时打开对话框
  4. 当选择文件时,使用onchange事件提交表单

这只是理论上的,因为我已经用了另一种方法来解决这个问题,但它可能会起作用。

我一整天都在寻找解决办法。以下是我得出的结论:

  1. 出于安全原因,Opera和Firefox不允许触发文件输入。
  2. 唯一方便的选择是创建一个“隐藏”文件输入(使用不透明,而不是“隐藏”或“显示:none”!),然后在它下面创建按钮。通过这种方式,按钮是可见的,但用户单击它实际上激活了文件输入。

希望这能有所帮助!:)

<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>

对于那些知道你必须在链接上覆盖一个看不见的表单,但懒得写的人,我为你写了它。对我来说是,但还是分享吧。欢迎提出意见。

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

这将在Firefox 4中实现,但需要注意的是,它被视为一个弹出窗口,因此无论何时弹出窗口都将被阻止。

您可以在任何浏览器上触发click(),但有些浏览器需要元素是可见和聚焦的。下面是一个jQuery示例:

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

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

这个代码适用于我。这就是你想做的吗?

<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>
以下是对我有效的解决方案: 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;
}

HTML与“小”JQuery帮助:

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

只是要确保maskfied被true upload字段完全覆盖。

我有一个<input type="button">标签隐藏在视图中。我所做的是将"onClick"事件附加到任何类型的可见组件,如标签。这是使用谷歌Chrome的开发工具或Mozilla Firefox的Firebug使用右键单击“编辑HTML”命令完成的。在这种情况下,指定以下脚本或类似的东西:

如果你有JQuery:

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

如果不是:

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

谢谢。

如果你想让click方法在Chrome、Firefox等上工作,请将以下样式应用到输入文件。它会被完全隐藏,就像你做了一个display: none;

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

就是这么简单,我测试过了!

这是可能的: 在FF4+、Opera ?、Chrome下: 但是:< / p >

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

  2. <input type="file" />应该是可见的(inputElement.style.display !== 'none')(你可以用可见性或其他东西隐藏它,但不能用"display"属性)

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

$("<input type='file' class='ui-helper-hidden-accessible' />").appendTo("body").focus().trigger('click');
$(document).one('mousemove', function() { $(element).trigger('click') } );

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

< >强工作的解决方案 < / >强

让我在这篇旧文章中补充一点,我曾经使用的一个有效的解决方案,在80%或以上的新老浏览器中都有效。

解决方案复杂而简单。第一步是使用CSS和伪装输入文件类型的“下元素”,显示通过,因为它的不透明度为0。下一步是根据需要使用JavaScript更新其标签。

超文本标记语言 如果你想快速访问一个特定的元素,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 纯粹和真实的,然而,一些旧的(退休)浏览器可能仍然有问题(像netscrap2 !

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

< a href = " http://jsfiddle.net/SpYk3/8fTfY/ " rel =“nofollow”> < h1 >工作jsFiddle示例< / h1 > < / >

你可以按照打开文件对话框<a>标签的答案来做

<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>

我发现如果输入(文件)是外部形式,那么触发单击事件调用文件对话框。

希望这能帮助到一些人——我花了2个小时用头撞它:

在IE8或IE9中,如果你用javascript以任何方式触发打开一个文件输入(相信我,我都试过了),它不会让你用javascript提交表单,它会默默地失败。

通过常规的提交按钮提交表单可以工作,但调用form.submit();会默默失败。

我不得不使用一个透明的文件输入来覆盖我的选择文件按钮。

它是有效的:

出于安全原因,在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">

这招对我很管用:

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


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


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

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

也就是说,到今天为止,fileInput.click()可以在当前的Chrome (36.0.1985.125 m)和当前的Firefox ESR(24.7.0)中工作,但不能在当前的IE(11.0.9600.17207)中工作。在一个按钮的顶部覆盖一个不透明度为0的文件字段是可行的,但是我想要一个链接元素作为可见的触发器,并且悬停下划线在任何浏览器中都不太适用。它闪烁着然后消失了,可能是浏览器在考虑是否实际应用悬浮样式。

但我确实找到了一个在所有这些浏览器中都能工作的解决方案。我不会说我测试过所有浏览器的每个版本,也不会说我知道它会一直工作下去,但它现在似乎满足了我的需求。

这很简单:将文件输入字段定位到屏幕外(Position: absolute;顶部:-5000px),在它周围放一个标签元素,并触发标签上的点击,而不是文件字段本身。

请注意,链接需要编写脚本来调用标签的click方法,它不会自动完成,就像单击标签元素中的文本一样。显然,link元素捕获了点击,而没有传递到标签。

还要注意,这并没有提供显示当前所选文件的方法,因为该字段是屏幕外的。我想在文件被选中时立即提交,所以这对我来说不是问题,但如果您的情况不同,您将需要某种不同的方法。

只是使用一个标签标签,这样你可以隐藏输入,并使它通过其相关标签工作 https://developer.mozilla.org/fr/docs/Web/HTML/Element/Label < / p >

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

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

这并非不可能:

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

但它只有在通过click-event调用的函数中才能工作。

所以你可能有以下设置:

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

下面是这个问题的纯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>

你可以使用

<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>
嘿,这个解决方案有效。 为了下载,我们应该使用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。

要做到这一点,你可以点击文件输入上的一个不可见的传递元素:

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)
}