HTML5文件API使用Ajax上传多个图像

HTML5 File API Upload Multiple Images with Ajax

本文关键字:图像 Ajax 文件 API 使用 HTML5      更新时间:2024-02-04

我正在尝试使用File API上传多个图像。我想将图片缩略图及其名称显示为标题标签。问题是我没有得到正确的图片名称作为标题标签。所有图片都显示相同的名称。这是我的原始代码。。。

jQuery、CSS和HTML

var output = document.getElementById("result");
$(document).ready(function ()
{
    //Check File API support
    if (window.File && window.FileList && window.FileReader)
    {
        $('#files').on("change", function (event)
        {
            var files = event.target.files; //FileList object
            var iCount = files.length;
            for (var i = 0, f; i < iCount; i++)
            {
                var file = files[i];
                //Only pics
                if (file.type.match('image.*'))
                {
                    var picReader = new FileReader();
                    picReader.addEventListener("load", function (event)
                    {
                        var picFile = event.target;
                        var div = document.createElement("div");
                        div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
                        "title='" + file['name'] + "'/>";
                        output.insertBefore(div, null);
                        
                    });
                    //Read the image
                    $('#clear, #result').show();
                    picReader.readAsDataURL(file);
                }
                else
                {
                    alert("You can only upload image file.");
                    $(this).val("");
                }
            }
        });
    }
    else
    {
        console.log("Your browser does not support File API");
    }
    $("#upload").on('submit',(function()
    {
        var data = new FormData(this);
        var iUploaded = 0;
        
        setTimeout(function()
        {
            var iCount = document.getElementById('files').files.length;
            
            for (var i = 0; i < iCount ; i++)
            {
                data.append("Index", i);
                $.ajax(
                {
                    url: "upload.php",
                    type: "POST",
                    data: data,
                    contentType: false,
                    cache: false,
                    processData:false,
                    async: false,
                    success: function(response)
                    {
                        var sRes = response.split("|-|");
                        
                        if(sRes['0'] == 'success')
                        {
                            iUploaded = iUploaded + 1;
                            $("#message").html(iUploaded + " of " + sRes['1'] + " Pictures Uploaded")
                        }
                    }
                });
            }
        }, 500);
    }));
    
    $("#files").change(function()
    {
        $("#submit").trigger("click");
    });
    $('#clear').on("click", function ()
    {
        $('.thumbnail').parent().remove();
        $('#result').hide();
        $('#files').val("");
        $(this).hide();
    });
});
body{
            font-family: 'Segoe UI';
            font-size: 12pt;
        }
        header h1{
            font-size:12pt;
            color: #fff;
            background-color: #1BA1E2;
            padding: 20px;
        }
        article
        {
            width: 80%;
            margin:auto;
            margin-top:10px;
        }
        .thumbnail{
            height: 100px;
            margin: 10px;
            float: left;
        }
        #clear{
            display:none;
        }
        #result {
            border: 4px dotted #cccccc;
            display: none;
            float: left;
            margin:0 auto;
        }
        #result > div {
            float: left;
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<article>
    <form id="upload" onsubmit="return false">
        <label for="files">Select multiple files: </label><br /><br />
        <input id="files" name="files[]" type="file" multiple/><br /><br />
        <input type="Submit" value="submit" id="submit"></input>
        <button type="button" id="clear">Clear</button><br /><br />
    </form>
    <div id="message"></div>
    <output id="result" />
</article>

我试着弄清楚,并知道var i的值在内自动变化

addEventListener("load", function (event){ // value of “var i” is not the same here as the value coming from outside this function. });

我不知道为什么值在"load"函数中发生变化。

我在谷歌上搜索了一下其他人是如何做的,最后在SitePoint上找到了这个工作示例http://www.sitepoint.com/html5-file-drag-and-drop/在这个例子中,我看到了这两个我不理解的主要区别(我在编程方面的知识很少)。

1.他在示例中使用的for循环的语法

for (var i = 0, f; f = files[i]; i++) {

请参阅,他正在为var f赋值,而不是应用停止条件。现在我的问题是,在没有指定停止条件的情况下,循环是如何工作的?

2.读取文件的独立功能

他制作了一个单独的函数ParseFile();来读取文件。当我尝试在没有单独的文件读取功能的情况下读取文件时,它不起作用(如我的原始代码所示)。但是,当我把代码放在一个单独的函数showThumbnail()中用于读取文件并在循环中调用该函数时,它就可以正常工作了(如下面的代码片段所示)。为什么会这样?

这里的任何人都可以向我解释这两件事。提前谢谢。

我按照这个例子重新排列了我的代码,它可以正常工作。(代码在下面的代码段中。)

var output = document.getElementById("result");
$(document).ready(function ()
{
    //Check File API support
    if (window.File && window.FileList && window.FileReader)
    {
        $('#files').on("change", function (event)
        {
            var files = event.target.files; //FileList object
            var iCount = files.length;
            for (var i = 0, f; f = files[i]; i++)
            {
                showThumbnail(f);
            }
        });
    }
    else
    {
        console.log("Your browser does not support File API");
    }
    $("#upload").on('submit',(function()
    {
        var data = new FormData(this);
        var iUploaded = 0;
        
        setTimeout(function()
        {
            var iCount = document.getElementById('files').files.length;
            
            for (var i = 0; i < iCount ; i++)
            {
                data.append("Index", i);
                $.ajax(
                {
                    url: "upload.php",
                    type: "POST",
                    data: data,
                    contentType: false,
                    cache: false,
                    processData:false,
                    async: false,
                    success: function(response)
                    {
                        var sRes = response.split("|-|");
                        
                        if(sRes['0'] == 'success')
                        {
                            iUploaded = iUploaded + 1;
                            $("#message").html(iUploaded + " of " + sRes['1'] + " Pictures Uploaded")
                        }
                    }
                });
            }
        }, 500);
    }));
    
    $("#files").change(function()
    {
        $("#submit").trigger("click");
    });
    $('#clear').on("click", function ()
    {
        $('.thumbnail').parent().remove();
        $('#result').hide();
        $('#files').val("");
        $(this).hide();
    });
});
function showThumbnail(file)
{
    //Only pics
    if (file.type.match('image.*'))
    {
        var picReader = new FileReader();
        picReader.addEventListener("load", function (event)
        {
            var picFile = event.target;
        
            var div = document.createElement("div");
            div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
            "title='" + file['name'] + "'/>";
            output.insertBefore(div, null);
            
        });
        //Read the image
        $('#clear, #result').show();
        picReader.readAsDataURL(file);
    }
    else
    {
        alert("You can only upload image file.");
        $(this).val("");
    }
}
 body{
            font-family: 'Segoe UI';
            font-size: 12pt;
        }
        header h1{
            font-size:12pt;
            color: #fff;
            background-color: #1BA1E2;
            padding: 20px;
        }
        article
        {
            width: 80%;
            margin:auto;
            margin-top:10px;
        }
        .thumbnail{
            height: 100px;
            margin: 10px;
            float: left;
        }
        #clear{
            display:none;
        }
        #result {
            border: 4px dotted #cccccc;
            display: none;
            float: left;
            margin:0 auto;
        }
        #result > div {
            float: left;
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<article>
    <form id="upload" onsubmit="return false">
        <label for="files">Select multiple files: </label><br /><br />
        <input id="files" name="files[]" type="file" multiple/><br /><br />
        <input type="Submit" value="submit" id="submit"></input>
        <button type="button" id="clear">Clear</button><br /><br />
    </form>
    <div id="message"></div>
    <output id="result" />
</article>

发布前未看到对问题的编辑+误读
因此,对于您的问题:

  • 1此for循环正在等待未定义文件[i]。:
    for( var i=0, f; f=files[i]; i++)
    如果files[x]未定义,则循环停止(即使定义了文件[x+1])

  • 2这是因为在第一个代码段中,file变量在全局范围内,并在迭代过程中被替换。然而,在第二个例子中,它被链接到showThumbnail函数范围,然后在EventListener中传递
    为了避免调用外部函数,您需要调用file绑定函数:

来自mdn:reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);

所以对你来说,

picReader.addEventListener("load", (function(aImg) { return function (event)
                    {
                        var picFile = event.target;
                        console.log(picFile);
                        var div = document.createElement("div");
                        div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
                        "title='" + aImg['name'] + "'/>";
                        output.insertBefore(div, null);
                    }; })(file));

以下示例:

var output = document.getElementById("result");
$(document).ready(function ()
{
    //Check File API support
    if (window.File && window.FileList && window.FileReader)
    {
        $('#files').on("change", function (event)
        {
            var files = event.target.files; //FileList object
            var iCount = files.length;
            for (var i = 0, f; i < iCount; i++)
            {
                var file = files[i];
                //Only pics
                if (file.type.match('image.*'))
                {
                    var picReader = new FileReader();
                    picReader.addEventListener("load", (function(aImg) { return function (event)
                    {
                        var picFile = event.target;
                        console.log(picFile);
                        var div = document.createElement("div");
                        div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
                        "title='" + aImg['name'] + "'/>";
                        output.insertBefore(div, null);
                        
                    }; })(file));
                    //Read the image
                    $('#clear, #result').show();
                    picReader.readAsDataURL(file);
                }
                else
                {
                    alert("You can only upload image file.");
                    $(this).val("");
                }
            }
        });
    }
    else
    {
        console.log("Your browser does not support File API");
    }
    $("#upload").on('submit',(function()
    {
        var data = new FormData(this);
        var iUploaded = 0;
        
        setTimeout(function()
        {
            var iCount = document.getElementById('files').files.length;
            
            for (var i = 0; i < iCount ; i++)
            {
                data.append("Index", i);
                $.ajax(
                {
                    url: "upload.php",
                    type: "POST",
                    data: data,
                    contentType: false,
                    cache: false,
                    processData:false,
                    async: false,
                    success: function(response)
                    {
                        var sRes = response.split("|-|");
                        
                        if(sRes['0'] == 'success')
                        {
                            iUploaded = iUploaded + 1;
                            $("#message").html(iUploaded + " of " + sRes['1'] + " Pictures Uploaded")
                        }
                    }
                });
            }
        }, 500);
    }));
    
    $("#files").change(function()
    {
        $("#submit").trigger("click");
    });
    $('#clear').on("click", function ()
    {
        $('.thumbnail').parent().remove();
        $('#result').hide();
        $('#files').val("");
        $(this).hide();
    });
});
body{
            font-family: 'Segoe UI';
            font-size: 12pt;
        }
        header h1{
            font-size:12pt;
            color: #fff;
            background-color: #1BA1E2;
            padding: 20px;
        }
        article
        {
            width: 80%;
            margin:auto;
            margin-top:10px;
        }
        .thumbnail{
            height: 100px;
            margin: 10px;
            float: left;
        }
        #clear{
            display:none;
        }
        #result {
            border: 4px dotted #cccccc;
            display: none;
            float: left;
            margin:0 auto;
        }
        #result > div {
            float: left;
        }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<article>
    <form id="upload" onsubmit="return false">
        <label for="files">Select multiple files: </label><br /><br />
        <input id="files" name="files[]" type="file" multiple/><br /><br />
        <input type="Submit" value="submit" id="submit"></input>
        <button type="button" id="clear">Clear</button><br /><br />
    </form>
    <div id="message"></div>
    <output id="result" />
</article>

问题1的答案:

for循环在每次迭代中将i递增1。当i不是files的索引时,返回的值将是未定义的,这会中断循环。

问题2的答案:

我创建了一个fidd,它展示了如何将showThumbnail的代码放入for循环中。它也解释了这个问题。

原因是addEventListener函数,它将在触发load后与for循环异步运行,并且具有不同的作用域。然而,循环外的函数是永久的,侦听器可以使用在该范围内声明的变量(参数file)。

但是,您可以做的是将侦听器函数绑定到文件对象。函数的作用域(this)将是文件。看看小提琴,让它发挥作用。