触发器在异步ajax done()上单击input = file

ale*_*lex 32 jquery

我有一个包含一些数据和上传的表单.只有在成功接收和处理数据后才能启动上载.为此,我在我的地方进行ajax调用

  1. 发送数据,
  2. 检查结果,
  3. 触发click()打开文件对话框.

click()的最后一件事不起作用,因为似乎异步调用块打开了一个上传窗口.它只有在我设置时才有效async: false.

我在文档和本网站中找不到任何内容,想知道那里有什么问题,以及如何让它保持调用异步?

例:

$.ajax({
    type: "POST",
    url: "/Save",
    data: jsonText,
    dataType: "json",
    //async: false            [1]
}).done(function (msg) {    
    $("#upload").click();   
});

//$("#upload").click();       [2]
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/c2v00uxn/

注意:

  • 如果我取消注释[1]或[2],它确实有效(文件对话框按预期显示).
  • 用触发器替换click()('click')不起作用
  • 用live()/ on()替换click()没有帮助
  • 文件上传控件是可见的(所以它不是因为隐藏控件)
  • ajax的超时设置没有帮助.

UPDATE

它不是关于如何一般地进行"点击",而是关于如何在异步ajax调用之后单击(截至目前,仅适用于非异步调用).

tka*_*kay 32

由于w3c推荐的浏览器安全功能,现在无法从异步ajax回调打开文件弹出窗口.

在文件输入元素的激活行为中,它首先检查是否允许算法显示弹出窗口,如果没有,则在不执行任何其他操作的情况下中止后续步骤.来自w3c.org

如果满足以下任一条件,则允许算法显示弹出窗口:

  1. 运行算法的任务当前正在处理其click事件受信任的激活行为.(受信任事件:由用户代理生成的事件,作为用户交互的结果,或作为对更改的直接结果) DOM,由用户代理信任,不具有脚本通过DocumentEvent.createEvent("Event")方法生成的事件,使用该Event.initEvent()方法修改或通过EventTarget.dispatchEvent()方法调度的特权.可信事件的isTrusted属性值为true,而不受信任的事件具有isTrusted属性值为false.否则为.http://www.w3.org/TR/2012/WD-DOM-Level-3-Events-20120614/#trusted-events.)
  2. 运行算法的任务当前正在为可信事件运行事件侦听器,其类型在以下列表中:

    • 更改
    • 点击
    • DBLCLICK
    • 鼠标松开
    • 重启
    • 提交
  3. 运行算法的任务由允许显示弹出窗口的算法排队,此类算法链在用户代理定义的时间范围内启动.

w3c.org

在您的代码中,click事件不是由用户触发,而是由ajax完成回调触发.这里浏览器声明无法信任该事件以打开弹出窗口.在某些浏览器中isTrusted,如果将事件声明为受信任,则可以看到属性设置为true.https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted

注意

不同的浏览器使用不同的方法捕获脚本激活的cick和真实用户之间的差异.

在这种情况下你可以做的是禁用文件输入按钮(或整个表单)并在ajax完成后启用.这样,在ajax请求完成之前,用户不会单击上传按钮.截至目前,没有其他方法可以在一次点击中同时执行这两种操作,因为打开弹出窗口也有时间限制.当我签入chrome时,时间范围是1000ms.用户操作后1000ms,窗口将无法打开.