需要对HTML5 fileAPI中的Javascript进行澄清,以进行图像预览 [英] Clarification required on Javascript in HTML5 fileAPI for image preview

查看:122
本文介绍了需要对HTML5 fileAPI中的Javascript进行澄清,以进行图像预览的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看新的HTML5文件API,以显示要上传的图像的预览.我用谷歌搜索了一些代码,几乎每个示例都具有相同的结构,几乎相同的代码.我不介意复制,尤其是当它可以工作时,但我需要了解它.因此,我试图理解代码,但是我只停留在一个领域,需要有人来解释这一小部分:

I was looking at the new HTML5 file API for showing a preview of an image to be uploaded. I googled for some code and almost every example had the same structure, almost the same code. I don't mind copying, particularly when it works, but I need to understand it. So I tried to understand the code but I am stuck with one area and need someone to explain that small part:

该代码引用HTML表单输入字段,并且在选择文件时在img标签中显示预览图像.没有什么花哨.简单的.这是消除所有噪音之后的情况:

The code refers to a HTML form input field and when the file is selected shows the preview image in a img tag. Nothing fancy. Simple. Here it is after removing all the noise:

 $('input[type=file]').change(function(e) {
     var elem = $(this);
     var file = e.target.files[0];
     var reader = new FileReader();

   //Part I could not understand starts here
   reader.onload = (function(theFile) {
     return function(e) {
        var image_file = e.target.result            
        $('#img_id').attr('src',image_file);
     };
   })(file);
   reader.readAsDataURL(file);
   //Upto here
 });

我认为需要为reader.onload分配一个普通的事件处理程序,因此我将上面标记的整个部分替换为:

I think that reader.onload needs to be assigned a plain event handler, so I replaced the entire section marked above to:

    reader.readAsDataURL(file);
    reader.onload = function(e) {
      var image_file = e.target.result;         
      //#img_id is the id of an img tag 
       $('#img_id').attr('src',image_file)
    };

它按我预期的那样工作.

And it worked as I expected it to work.

问题:上面的简化代码丢失了什么原始代码?我知道这是一个函数表达式,它先返回一个函数,然后再调用它……但是为什么呢?在教程中复制的原始代码太多了,没有写在上面,但没有很好的解释.请解释.谢谢

QUESTION: What's the original code doing that the above simplified code is missing? I understand that it is a function expression returning a function and then calling it… but for what? There is just too much of the original code copied around under tutorials and what not on it but no good explanation. Please explain. Thanks

推荐答案

可以.
函数包装函数在这里用于记住您正在查看哪个文件的特定目的.

Sure.
The function-wrapped function, here serves the specific purpose of remembering which file it was you were looking at.

使用确切的代码库,这可能没什么问题,但是如果您有一个多次上传小部件,并且想要显示一行预览:

This might be less of a problem using your exact codebase, but if you had a multiple-upload widget, and you wanted to display a row of previews:

var my_files = [].slice.call(file_input.files),

    file, reader,

    i = 0, l = my_files.length;


for (; i < l; i += 1) {
    file = my_files[i];
    reader = new FileReader();

    // always put the handler first (upside down), because this is async
    // if written normally and the operation finishes first (ie:cached response)
    // then handler never gets called
    reader.onload = function (e) {
        var blob_url = e.target.result,
            img = new Image();

        img.src = blob_url;
        document.body.appendChild(img);
    };
    reader.readAsDataUrl(file);
}

那应该一切正常. ...除了... 而且它很干净而且可读.

That should all work fine. ...except... And it's clean and readable.

正在解决的问题很简单:

The issue that was being resolved is simply this:

我们正在处理异步处理程序,这意味着在触发回调时,file的值不一定像以前一样...

We're dealing with async-handlers, which means that the value of file isn't necessarily the same when the callback fires, as it was before...

有很多方法可以解决这个问题.
几乎所有这些都不生成随机id/sequence-numbers/基于时间的哈希值以检查返回是否依赖于封闭.

There are a number of ways to potentially solve that.
Pretty much all of them that don't generate random ids/sequence-numbers/time-based hashes to check against on return, rely on closure.

当我可以将其包装到一个函数中并完成后,为什么还要创建一个完整的管理系统呢?

And why would I want to create a whole management-system, when I could wrap it in a function and be done?

var save_file_reference_and_return_new_handler = function (given_file) {
    return function (e) {
        var blob_url  = e.target.result,
            file_name = given_file.name;

        //...
    };
};

因此,如果您将其放在函数顶部(循环上方),则可以说:

So if you had that at the top of the function (above the loop), you could say:

reader = new FileReader();
reader.onload = save_file_reference_and_return_new_handler(file);
reader.readAsDataUrl(file);

现在它可以正常工作了.

And now it will work just fine.

当然,JS人员并不总是被迫编写命名函数,只是将其中一项存储在闭包中以备后用...

Of course, JS people don't always feel compelled to write named functions, just to store one item in closure to remember later...

reader.onload = (function (current_file) {
    return function (e) {
        var blob_url  = e.target.result,
            file_name = current_file.name;
    };
}(file));

这篇关于需要对HTML5 fileAPI中的Javascript进行澄清,以进行图像预览的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆