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

时间:2015-06-24 16:56:57

标签: javascript jquery html dialog

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

我有另一个标识为choose-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时,它确实到达了这个断点。但是,文件对话框永远不会显示。

通过调试,我发现如果我在alert(...);行之后放置#choose-file-button click(),则警报会显示正常页面“打开文件”对话框显示up(不是我的文件对话框)。但是,如果我没有这个警报,则根本没有任何显示。

这是一个错误吗?如何修复它并通过截获的Ctrl+O

显示我的文件对话框

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

4 个答案:

答案 0 :(得分:9)

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

编辑:怀疑,大多数浏览器会根据事件类型以及是由用户创建还是以编程方式生成来跟踪事件是否可信。请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)。 / LI>
  • 另一种方法是为drag-drop file uploading使用一种新的HTML5 JavaScript API。

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

答案 1 :(得分:4)

浏览器将许多Ctrl +快捷键映射到自己的命令,例如CTRL + O来打开文件(在firefox中)。

同时,当您尝试在javascript中覆盖此类快捷方式时,浏览器的行为会有所不同。有些浏览器允许您这样做,有些则不允许,有时默认的浏览器操作可能会与您的javascript操作一起弹出。

这是讨论这个topic的另一个主题。

您可以做的最好的事情就是选择不同的快捷方式。

答案 2 :(得分:4)

您可以尝试使用Mousetrap库。它覆盖了键捕获所带来的大多数问题。 官方网站和完整的参考:

https://craig.is/killing/mice

祝你好运

答案 3 :(得分:1)

你不能在所有浏览器中都这样做,只要我担心只有IE允许它。我想这是由于安全问题,因此程序员被禁用以自动在HTML File元素上设置文件名(未经客户端许可)。

查看此链接以获取更多详细信息:

In JavaScript can I make a "click" event fire programmatically for a file input element?

Show input file dialog on load?