对于不加载页面而是提供文件的表单,如何检测表单提交何时完成?


How can I detect when form submission is complete, for a form that does not load a page, but rather, serves up a file?

当我知道一个表单需要一段时间才能提交时,我喜欢在提交事件上显示一个加载指示器,这样它就会显示出来,然后在新页面加载时被清除,就像这样简单

$('#theForm').submit(function () {
    $('#loaderContainer').html('<img src="loader.gif" id="loadingGIF" />');
});

我遇到的问题是,我正试图为一个表单做这个,当你提交它时,它不会从页面导航,它只是提供一个文件。我在php渲染csv,并提供它。只要几秒钟只需要一分钟。当发生这种情况时,您永远不会离开页面,因此没有什么可以触发加载器消失。我想我可以提交到iframe,然后用iframe的onLoad事件杀死加载器:

<form action="/makeCSV" method="POST" target="iframe">

<iframe id="iframe" name="iframe"></iframe>
$("#iframe").load(function () {
    $("#loadingGIF").remove();
});

但是我猜因为它只是提供一个文件而不是加载一个页面,所以onload事件不会触发。

如果我有一个提供文件的表单,而不是导航到一个新页面,是否有任何方法来检测文件已经提供?

如果有帮助,csv渲染代码如下:

    <?php
    //do some stuff to generate a csv...
    $csv="heading1, heading2, heading3, heading4 'r'n";
    $csv.="value1, value2, value3, value4 'r'n";
    $csv.="a,b,c,d 'r'n";
    //...
    header('Pragma: public');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Cache-Control: private', false);
    header('Content-Type: text/csv');
    header("Content-Disposition: attachment;filename='"file.csv'"");
    echo $csv;
    exit;
    ?>

我将采用两步流程-通过ajax提交表单,构建csv,保存为临时文件并返回标识符。然后将iframe设置为请求文件,并在该请求的处理程序中删除该文件:

$('#form').submit(function(ev){
    ev.preventDefault();
    $('#loaderContainer').html('<img src="loader.gif" id="loadingGIF" />');
    $.post('createfile.php', $(this).serialize(), function(resp){
         var identifier = resp.intentifier;
         $('iframe').attr('src', 'servefile.php?i='+identifier);
         $('#loaderContainer').html('<!-- -->');
    }
}
//createfile.php
//create csv then
$identifier = uuid();
file_put_contents('somedir/'. $identifier .'.tmp', $csv);
echo json_encode(['indentifier'=>$identifier]);
//servefile.php
$identifier = $_GET['identifier'];
$file = 'somedir/' .$identifier .'.tmp'
//output correct headers here
readfile($file);
unlink($file);

既然您已经在使用JQuery,我建议您使用一些已经以紧凑/可靠的方式解决了问题的东西。我建议给jQuery文件下载一个尝试。

这个答案使我想到了它。这可能正是你需要的,它只是一个插件,你可以在你的项目和测试:)祝你好运。

你可以检查窗口失去焦点…很基本,但可以满足我的需要。

$([window, top.window]).blur(function() {
    $('BUTTON.btnLoading').removeClass('btnLoading');
});