拦截的Javascript“Ctrl O”不会打开我的文件对话框

我有一个< input type =“file”id =“browse-button”/>我的 HTML中的文件浏览器输入.

我有一个ID为select-file-button的按钮,当点击它时,调用document.getElementById(“browse-button”).click();.单击此按钮时,它会正确单击#browse-button并打开文件对话框.

现在,我从this answer获取代码拦截Ctrl O按键并打开我的文件对话框,所以我有这个:

$(window).bind('keydown',function(e)
{
    if (e.ctrlKey || e.MetaKey)
    {
        switch (String.fromCharCode(e.which).toLowerCase())
        {
            case 's':
                e.preventDefault();
                // doesn't matter for this question
                return false;
            case 'o':
                e.preventDefault();
                document.getElementById("choose-file-button").click();
                return false;
        }
    }
    return true;
});

如你所见,当我拦截Ctrl O时,我点击我的#choose-file-button按钮,它调用document.getElementById(“browse-button”);在其onclick处理程序中.我在这个点击处理程序中放了一个断点,当我按下Ctrl O时它会到达这个断点.但是,文件对话框永远不会显示.

通过调试,我发现如果我发出警报(…);在#choose-file-button click()行之后,出现警报并显示正常页面“Open File”对话框(不是我的文件对话框).但是,如果我没有此警报,则根本不显示任何内容.

这是一个错误吗?如何修复它并通过拦截的Ctrl O显示我的文件对话框?

编辑:我刚刚在Chrome中测试过,效果很好.但是,它仍然无法在Firefox中使用.

解决方法

这里有一些浏览器安全魔法.当我使用超时或间隔或我尝试的任何其他方法时,代码正常进行,但浏览器只是拒绝打开文件上载对话框.这可能是故意的,以阻止恶意JS在未经同意的情况下尝试获取用户文件.但是,如果绑定到链接上的单击事件,它将使用jQuery或常规JS完美地工作.

编辑:怀疑,大多数浏览器根据事件类型以及是由用户创建还是以编程方式生成来跟踪事件是否可信. Se this answer了解详情.如您所见,由于键盘事件不在列表中,因此永远不会信任它们.

Test JSFiddle

<form action="#" method="post">
    <div>
        <input type="file" id="myfile" name="myfile" /> <a href="#" id="mylink" accesskey="o">Click me</a>
    </div>
</form>

$("#mylink").click(function () {
    $("#myfile").click();
});

$(window).bind('keydown',function (e) {
    if (e.ctrlKey || e.MetaKey) {
        switch (String.fromCharCode(e.which).toLowerCase()) {
            case 'o':
                e.preventDefault();
                console.log("1a");

                $("#myfile").click();
                //alert("hello");

                console.log("1b");
                return false;
        }
    }
    return true;
});

我认为这里只有两种选择,它们都是解决方法,而不是解决方案.

>一种是使用链接来触发文件上传对话框,并要求人们使用ALT SHIFT O而不是CTRL O(因为我在示例中为链接添加accesskey attribute).
>另一种方法是使用drag-drop file uploading的新HTML5 JavaScript API之一.

附录:我还尝试在Firefox中使用纯JavaScript来获取点击事件,并使用isTrusted属性检查它是否可信.对于链接上的点击,它返回true.但是,尝试在其他地方存储和重新使用该事件不起作用,因为它在您获得引用时已经被调度.此外,不出所料,创建一个新事件并尝试设置isTrusted = true也不起作用,因为它是只读的.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...