如何避免 Firefox 中文件选择器 5 秒的“用户未激活”超时?

问题描述 投票:0回答:1

我试图避免单击

<input type="file">
元素时出现可怕的“选择器因缺乏用户激活而被阻止”错误。我知道您认为您以前多次看到过这个问题,但是等等。这个不一样。

大多数/所有其他问题都是关于以编程方式在文件输入元素上调度单击事件(

.click()
),但由于缺乏用户激活(即物理单击)而无法打开选择器。

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

如何使用 JavaScript 以编程方式打开文件选择器?

Firefox 无法覆盖 about:config 中的“ 选择器因缺乏用户激活而被阻止”

`` 选择器因以编程方式尝试打开文件加载对话框时缺乏用户激活而被阻止

这个问题涉及物理单击文件输入元素,但以交互方式检查用户是否真的想现在选择一个文件。

  1. 用户单击按钮(或看起来像按钮的东西)来加载文件。
  2. 如果有未保存的更改,程序会向用户发出警告。用户可以取消加载。
  3. 如果未取消,程序将打开文件选择器。用户选择一个文件。
  4. 程序用所选文件替换当前文件缓冲区内容。

我已经通过下面的第一个“按钮”实现了理想的流程(简化版本)。然而,有一个问题。如果用户等待超过 5 秒才决定加载文件,选择器将拒绝打开,并在控制台中记录“缺少用户激活”错误。

不太理想的是,我使用下面的第二个“按钮”实现了替代流程。

  1. 用户单击按钮(或看起来像按钮的东西)来加载文件。
  2. 程序打开一个文件选择器。用户选择一个文件。
  3. 如果有未保存的更改,程序会向用户发出警告。用户可以取消加载。
  4. 如果不取消,程序将用所选文件替换当前文件缓冲区内容。

( 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 解决方案特别感兴趣,即使它也可能适用于其他浏览器。

javascript firefox
1个回答
0
投票

感谢@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>

© www.soinside.com 2019 - 2024. All rights reserved.