我试图避免单击
<input type="file">
元素时出现可怕的“选择器因缺乏用户激活而被阻止”错误。我知道您认为您以前多次看到过这个问题,但是等等。这个不一样。
大多数/所有其他问题都是关于以编程方式在文件输入元素上调度单击事件(
.click()
),但由于缺乏用户激活(即物理单击)而无法打开选择器。
在 JavaScript 中,我可以通过编程方式为文件输入元素触发“click”事件吗?
Firefox 无法覆盖 about:config 中的“ 选择器因缺乏用户激活而被阻止”
`` 选择器因以编程方式尝试打开文件加载对话框时缺乏用户激活而被阻止
这个问题涉及物理单击文件输入元素,但以交互方式检查用户是否真的想现在选择一个文件。
我已经通过下面的第一个“按钮”实现了理想的流程(简化版本)。然而,有一个问题。如果用户等待超过 5 秒才决定加载文件,选择器将拒绝打开,并在控制台中记录“缺少用户激活”错误。
不太理想的是,我使用下面的第二个“按钮”实现了替代流程。
( function () {
'use strict';
function onChange1( e ) {
alert( 'contents overwritten' );
}
function onClick1( e ) {
if (
!confirm(
'There are unsaved changes.\n' +
'Is it OK to discard them?' )
) {
e.preventDefault();
}
}
function onChange2() {
if (
confirm(
'There are unsaved changes.\n' +
'Is it OK to discard them?' )
) {
alert( 'contents overwritten' );
}
}
function onContentLoaded() {
var
input1 = document.getElementById( 'input1' ),
input2 = document.getElementById( 'input2' );
input1.addEventListener( 'click', onClick1 );
input1.addEventListener( 'change', onChange1 );
input2.addEventListener( 'change', onChange2 );
}
document.addEventListener( 'DOMContentLoaded', onContentLoaded, { once: true } );
} () );
div {
background-color: #eee;
display: inline-block;
}
input {
display: none;
}
label {
line-height: 2;
padding: 0.5em;
}
<!DOCTYPE html><html lang="en"><head>
<title>Stack Overflow QA</title>
<link rel="stylesheet" href="page.css">
<script src="page.js"></script>
</head><body>
<div><label><input id="input1" type="file">Open File 1 ...</label></div>
<div><label><input id="input2" type="file">Open File 2 ...</label></div>
</body></html>
我真的更喜欢第一个流程,所以我想找到一种绕过 5 秒超时的方法。我对 Firefox 解决方案特别感兴趣,即使它也可能适用于其他浏览器。
感谢@GuyIncognito 的评论,这是我的(最小)解决方案。
( function () {
'use strict';
function onChange() {
// just a status update, nothing real
alert( 'contents overwritten' );
}
function onClickDialog( e ) {
if ( e.target.id === 'OK' ) {
// pass the click along
document.getElementById( 'input' ).click();
}
// re-hide the dialog
document.getElementById( 'modal' ).classList = 'hidden';
}
function onClickFile() {
// unhide the dialog
document.getElementById( 'modal' ).classList = '';
}
function onContentLoaded() {
document.getElementById( 'button' ).addEventListener( 'click', onClickFile );
document.getElementById( 'OK' ).addEventListener( 'click', onClickDialog );
document.getElementById( 'Cancel' ).addEventListener( 'click', onClickDialog );
document.getElementById( 'input' ).addEventListener( 'change', onChange )
}
document.addEventListener( 'DOMContentLoaded', onContentLoaded, { once: true } );
} () );
button {
font-size: inherit;
}
input,
.hidden {
display: none;
}
#modal {
background-color: #0001;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
#dialog {
background-color: #fff;
display: inline-block;
left: 50%;
padding: 1em;
position: relative;
top:50%;
transform: translate( -50%, -50% );
}
<!DOCTYPE html><html lang="en"><head>
<title>Stack Overflow QA</title>
<link rel="stylesheet" href="page.css">
<script src="page.js"></script>
</head><body>
<div id="modal" class="hidden"><div id="dialog">
<p>There are unsaved changes.</p>
<p>Is it OK to discard the changes?</p>
<button id="OK">OK</button> <button id="Cancel">Cancel</button>
</div></div>
<button id="button">Open File ...</button>
<input id="input" type="file">
</body></html>