简体   繁体   English

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

[英]Javascript Intercepted “Ctrl+O” Does Not Open My File Dialog

I have an <input type="file" id="browse-button"/> file-browser input in my HTML. 我的HTML中有一个<input type="file" id="browse-button"/>文件浏览器输入。

I have another button with ID choose-file-button that, when clicked, calls document.getElementById("browse-button").click(); 我还有另一个带有ID choose-file-button ,单击该choose-file-button时会调用document.getElementById("browse-button").click(); . When this button is clicked, it correctly clicks #browse-button and the file dialog opens. 单击此按钮后,它会正确单击#browse-button然后将打开文件对话框。

Now, I took code from this answer to intercept a Ctrl+O keypress and open my file dialog, so I have this: 现在,我从该答案中获取了代码,以拦截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;
});

As you can see, when I intercept Ctrl+O I click on my #choose-file-button button, which calls document.getElementById("browse-button"); 如您所见,当我拦截Ctrl+O我单击了#choose-file-button按钮,该按钮调用document.getElementById("browse-button"); in its onclick handler. 在其onclick处理程序中。 I have put a breakpoint in this click handler, and when I press Ctrl+O it does arrive at this breakpoint. 我在此单击处理程序中放置了一个断点,当我按Ctrl+O它确实到达了该断点。 However, the file dialog never shows up. 但是,文件对话框永远不会显示。

Through debugging, I found out that if I put an alert(...); 通过调试,我发现是否发出alert(...); after the #choose-file-button click() line, then the alert shows up and the normal page "Open File" dialog shows up (not my file dialog). #choose-file-button click()行之后,将显示警报, 显示正常页面的“打开文件”对话框(不是我的文件对话框)。 If I do not have this alert, however, nothing shows up at all. 但是,如果我没有此警报,则什么都不会显示。

Is this a bug? 这是错误吗? How can I fix it and make my file dialog show up via the intercepted Ctrl+O ? 我该如何解决它,并通过截获的Ctrl+O使我的文件对话框显示出来?

Edit: I just tested in Chrome, and it works perfectly. 编辑:我刚刚在Chrome中进行了测试,并且效果很好。 However, it still does not work in Firefox. 但是,它仍然无法在Firefox中使用。

There's some browser security magic going on here. 这里有一些浏览器安全魔术。 When using timeouts or intervals or any other methods I try, the code carries on as normal but the browser simply refuses to open a file upload dialog. 当使用超时或间隔或我尝试的任何其他方法时,代码会像往常一样进行,但是浏览器只是拒绝打开文件上传对话框。 This is probably deliberate, to stop malicious JS from trying to grab users' files without consent. 这可能是有意的,目的是阻止恶意JS试图在未经许可的情况下获取用户文件。 However, if you bind to a click event on a link, it works perfectly using jQuery or regular JS. 但是,如果您绑定到链接上的click事件,则使用jQuery或常规JS可以完美地工作。

Edit: As suspected, most browsers keep track of whether an event is trusted or not based on the type of event and whether it was created by the user or generated programmatically. 编辑:怀疑,大多数浏览器会根据事件的类型以及事件是由用户创建还是以编程方式生成的,来跟踪事件是否受信任。 Se this answer for the full details. 请使用此答案以获取全部详细信息。 As you can see, since keyboard events aren't in the list, they can never be trusted. 如您所见,由于键盘事件不在列表中,所以它们永远不会被信任。

Test JSFiddle 测试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;
});

I think there are only two options here, and they're both workarounds, not solutions. 我认为这里只有两种选择,它们都是解决方法,而不是解决方案。

  • One is to use a link to trigger the file upload dialog, and ask people to use ALT+SHIFT+O instead of CTRL+O (because I added an accesskey attribute to the link in the example). 一种是使用链接触发文件上传对话框,并要求人们使用ALT + SHIFT + O而不是CTRL + O(因为在示例中,我向该链接添加了accesskey属性 )。
  • The other alternative is to use one of the new HTML5 JavaScript APIs for drag-drop file uploading . 另一种选择是使用新的HTML5 JavaScript API之一进行拖放文件上传

Addendum: I also tried using pure JavaScript in Firefox to grab a click event and check to see if it's trusted using the isTrusted property. 附录:我还尝试在Firefox中使用纯JavaScript来捕获click事件,并使用isTrusted属性检查它是否受信任。 For the clicks on the link, it returned true . 对于链接的点击,返回true However, attempting to store and re-use the event elsewhere doesn't work, because it's already been dispatched by the time you get a reference to it. 但是,尝试在其他地方存储和重用该事件不起作用,因为在您获得对该事件的引用时该事件已经被调度。 Also, unsurprisingly, creating a new event and attempting to set isTrusted = true doesn't work either since it's read-only. 同样,毫不奇怪,创建新事件并尝试将isTrusted = true设置为isTrusted = true ,因为它是只读的。

Browser map many Ctrl+ shortcuts to own commands, for instance CTRL+O to open a file (in firefox). 浏览器将许多Ctrl +快捷键映射到自己的命令,例如CTRL + O打开文件(在firefox中)。

On the same time browser behave different when you try to override such shortcuts in javascript. 同时,当您尝试覆盖javascript中的此类快捷方式时,浏览器的行为也有所不同。 Some browsers allow you to do so, some don't, and sometimes the default browser action may pop up together with the action of your javascript. 有些浏览器允许您这样做,有些则不允许,有时默认浏览器操作可能会与JavaScript操作一起弹出。

Here is another thread discussing this topic . 这是讨论该主题的另一个主题

Probably the best you can do is to choose a different shortcut. 您可能最好的选择是选择其他快捷方式。

You can try with Mousetrap library. 您可以尝试使用捕鼠器库。 It overrides the most problems that key capturing makes. 它覆盖了密钥捕获带来的大多数问题。 Official website and complete refference: 官方网站和完整参考:

https://craig.is/killing/mice https://craig.is/killing/mice

Good luck 祝好运

You cannot do that in all browsers, as far as I am concern only IE allow it. 就我而言,您不能在所有浏览器中都做到这一点,只有IE允许它。 I guess this is due to security issues, so that programmer are disabled to set the file name on the HTML File element automatically(without permission of client). 我猜这是由于安全问题引起的,因此程序员被禁止自动在HTML File元素上设置文件名(未经客户端许可)。

have a look on this link for more details: 请查看此链接以获取更多详细信息:

In JavaScript can I make a "click" event fire programmatically for a file input element? 我可以在JavaScript中以编程方式为文件输入元素触发“点击”事件吗?

Show input file dialog on load? 在加载时显示输入文件对话框?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM