跟踪基本HTML表单发布进度

时间:2014-09-04 14:58:46

标签: javascript jquery forms post

我有一个正常提交的基本HTML表单,根本没有ajax。此表单使用常规帖子提交到同一文件。我不使用AJAX,因为表单有12个文本字段和至少1个图像,但最多可能有26个图像和ajax不能同时执行两个表单和图像,我必须保存到数据库,这是很多关于AJAX的额外工作。

问题是我需要以某种方式跟踪表单上传进度。大多数程序员都知道在浏览器的左下角或右下角查看表单提交进度。但是大多数人都不知道这一点。

所以我想显示一个进度条。问题是我发现使用ajax的XHR请求的所有进度条。由于表单不是ajax,我似乎找不到跟踪进度的方法。

那么有没有办法拦截浏览器内部提交进度以查看表单上传完成的百分比?

修改

我在页面开头尝试了以下代码,但它不起作用。我猜是因为XHR用于AJAX或浏览器有自己的需要劫持,但我不知道会被调用什么或者如何获得它如果是这样:

xhr = new XMLHttpRequest();
xhr.upload.addEventListener( "progress", function ( evt )
{
    if( evt.lengthComputable )
    {
        var progressPercent = ( evt.loaded / evt.total ) * 100;
        console.log( value );
    }
}, false );

2 个答案:

答案 0 :(得分:3)

这是我有时使用的某种渐进增强。它仍然会以最透明的方式为用户和开发人员提出ajax请求。 关键是通过FormData发布与常规表单发布完全相同的数据,并在我们从服务器收到整页响应时替换整个文档。这是一个未经测试的简化版本:

function enhanceFormWithUploadProgress(form, progress) {
//form : the HTML form element to enhance.
//progress : an HTML element that will display upload progress.

    //testing browser support. if no support for the required js APIs, the form will just be posted naturally with no progress showing.
    var xhr = new XMLHttpRequest();
    if (!(xhr && ('upload' in xhr) && ('onprogress' in xhr.upload)) || !window.FormData) {
        return;
    }

    form.addEventListener('submit', function(e) {
        //prevent regular form posting
        e.preventDefault();

        xhr.upload.addEventListener('loadstart', function(event) {
            //initializing the progress indicator (here we're displaying an element that was hidden)
            progress.style.display = 'block';
        }, false);

        xhr.upload.addEventListener('progress', function(event) {
            //displaying the progress value as text percentage, may instead update some CSS to show a bar
            var percent = (100 * event.loaded / event.total);
            progress.innerHTML = 'Progress: ' + percent.toFixed(2) + '%';
        }, false);

        xhr.upload.addEventListener('load', function(event) {
            //this will be displayed while the server is handling the response (all upload data has been transmitted by now)
            progress.innerHTML = 'Completed, waiting for response...';
        }, false);

        xhr.addEventListener('readystatechange', function(event) {
            if (event.target.readyState == 4 && event.target.responseText) {
                //we got a response from the server and we're replacing the whole current document content with it, simulating a page reload
                var newDocument = document.open('text/html', 'replace');
                newDocument.write(event.target.responseText);
                newDocument.close();
            } else {
                throw new Error('Error in the response.');
            }
        }, false);

        //posting the form with the same method and action as specified by the HTML markup
        xhr.open(this.getAttribute('method'), this.getAttribute('action'), true);
        xhr.send(new FormData(this));

    });

};

答案 1 :(得分:0)

HTML:

<form method="post">
    <button type="submit">Submit</button>
</form>

JavaScript的:

/*
Show a progress element for any form submission via POST.
Prevent the form element from being submitted twice.
*/
(function (win, doc) {
    'use strict';
    if (!doc.querySelectorAll || !win.addEventListener) {
        // doesn't cut the mustard.
        return;
    }
    var forms = doc.querySelectorAll('form[method="post"]'),
        formcount = forms.length,
        i,
        submitting = false,
        checkForm = function (ev) {
            if (submitting) {
                ev.preventDefault();
            } else {
                submitting = true;
                this.appendChild(doc.createElement('progress'));
            }
        };
    for (i = 0; i < formcount; i = i + 1) {
        forms[i].addEventListener('submit', checkForm, false);
    }
}(this, this.document));

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

信用:https://gist.github.com/adactio/9315750