<label for="input">Label</label><input type="file" id="input"/>
在Firefox 7中,无法通过单击标签来触发打开的文件对话框。
This SO question非常相似,但用绿色检查这是FF 中的错误。我正在寻找一种解决方法。
有什么想法吗?
答案 0 :(得分:22)
谢谢你这个q&amp; a ...帮帮我。
@ marten-wikstrom解决方案的变体:
if($.browser.mozilla) {
$(document).on('click', 'label', function(e) {
if(e.currentTarget === this && e.target.nodeName !== 'INPUT') {
$(this.control).click();
}
});
}
注释
$(function() {...});
)。 jQuery.fn.live
在@ marten-wikstrom案件中处理这件事;在我的示例中明确绑定到document
。jQuery.fn.on
...当前推荐的绑定技术。添加了!== 'INPUT'
检查以确保执行不会在循环中被捕获:
<label>
<input type="file">
</label>
(因为文件字段点击会冒回泡标签)
将event.target
检查更改为event.currentTarget
,允许初次点击<em>
:
<label for="field">click <em>here</em></label>
control
属性来实现更清晰,更简单的基于规范的表单字段关联。答案 1 :(得分:2)
我提出了一个可行的解决方法:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("label").click(function () {
$("#input").click();
});
});
</script>
<label for="input">Label</label><input type="file" id="input"/>
很奇怪,FF允许您模拟文件输入的点击。我认为那被认为是一种安全隐患......
更新:这是一种通用的解决方法:
<script type="text/javascript">
$(function () {
if ($.browser.mozilla) {
$("label").live("click", function (event) {
if (event.target == this) {
$("#" + $(this).attr("for")).extend($("input", this)).first().click();
}
});
}
});
</script>
答案 2 :(得分:1)
使用jQuery浏览器检测时出现了一些问题,最明显的是使用浏览器检测而非功能检测的反模式,以及1.9+不提供该功能的事实。
那么,或许,我得到的解决方案有点虚伪,但它运作良好,似乎坚持今天最好的做法。
首先,确保您使用Paul Irish's conditional classes。然后,使用类似的东西:
if($("html").hasClass("ie")) {
$("label").click();
} else {
$("input").click();
}
否则,我发现该事件会在Chrome等浏览器中被双重触发。这个解决方案看起来很优雅。
答案 3 :(得分:1)
click()
event可以在所有浏览器中触发文件选择对话框。这个问题的一个不引人注目的解决方案可能是这样的:
$('label')
.attr('for', null)
.click(function() {
$('#input').click();
});
删除for
属性很重要,因为其他浏览器(例如Chrome,IE)仍会批准它并显示对话框两次。
我在Chrome 25,Firefox 19和IE 9中进行过测试,效果很好。
答案 4 :(得分:1)
似乎在FF 23中已修复,因此浏览器检测变得危险并导致双系统对话;(
您可以添加另一个测试以将修订限制为版本23之前的FF版本:
if(parseInt(navigator.buildID,10) < 20130714000000){
//DO THE FIX
}
这很难看,但是一旦FF版本消失,这个修复程序就会被删除。
答案 5 :(得分:0)
如果需要,您可以将事件从任何事件调度到type = file输入 输入display:none和visibility:hidden,然后从中调度事件, 比如,点击图像......
<img id="customImg" src="file.ext"/>
<input id="fileLoader" type="file" style="display:none;visibility:hidden"/>
<script>
customImg.addEventListener(customImg.ontouchstart?'touchstart':'click', function(e){
var evt = document.createEvent('HTMLEvents');
evt.initEvent('click',false,true);
fileLoader.dispatchEvent(evt);
},false);
</script>
答案 6 :(得分:0)
当您不需要/想要输入框(如图片上传)时,要在元素中使用opacity: 0
并在标签中使用pointer-events: none;
。
该解决方案实际上是针对特定设计的,但也许应该适合那些参与其中的人。 (直到现在这个bug还没有修复)
答案 7 :(得分:0)
在React
环境中使用上述Corey的答案,我必须执行以下操作:
(Firefox检查基于How to detect Safari, Chrome, IE, Firefox and Opera browser?)
const ReactFileInputButton = ({ onClick }) => {
const isFirefox = typeof InstallTrigger !== 'undefined';
const handleClick = isFirefox ? (e) => {
e.currentTarget.control.click();
} : undefined;
const handleFileSelect = (e) => {
if (e.target.files && e.target.files[0]) {
onClick({ file: e.target.files[0] });
}
}
return (
<>
<input type="file" id="file" onChange={handleFileSelect} />
<label htmlFor="file" onClick={handleClick}>
Select file
</label>
</>
);
};
答案 8 :(得分:-1)
反转标签和输入元素的顺序。嘿,把标签元素放在输入元素之后。
答案 9 :(得分:-1)
试试此代码
<img id="uploadPreview" style="width: 100px; height: 100px;"
onclick="document.getElementById('uploadImage').click(event);" />
<input id="uploadImage" type="file" name="myPhoto" onchange="PreviewImage();" />
<script type="text/javascript">
function PreviewImage() {
var oFReader = new FileReader();
oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
oFReader.onload = function (oFREvent) {
document.getElementById("uploadPreview").src = oFREvent.target.result;
};
};
</script>