文件上传之图片预览

一、业界现状分析
有时候我们需要在上传图片之前为用户提供图片预览的功能,HTML5规范出来之前,由于缺少原生的File API支持,我们需要借助Flash或者浏览器插件来满足这种需求。有了HTML5,我们可使用URL或者FileReader对象实现预览功能。
 
二、应用场景
图片分享类的应用,如Flickr,Facebook。相册应用,如:QQ相册。
虽然139邮箱没有合适的应用场景,但是可将技术预研的成果作为技术储备,好东西总有用得着的时候。
 
三、编码实现
方式一:window.URL
(1)、先看一下效果图:
 
 
(2)、HTML如下:
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files);this.value='';">
<a href="#" id="fileSelect">Select some files</a> 
<div id="fileList">
  <p>No files selected!</p>
</div
 
(3)、JS代码如下:
     window.URL = window.URL || window.webkitURL;
 
        var fileSelect = document.getElementById("fileSelect"), fileElem = document.getElementById("fileElem"), fileList = document.getElementById("fileList");
 
        fileSelect.addEventListener("click", function(e) {
            if (fileElem) {
             
             // 单击fileSelect调用input type='file'的单击事件就能弹出文件选择框,是不是很爽?
             // 低版本浏览器必须单击input type='file'才能弹出文件选择框,我在文件上传之普通上传的博文中介绍过解决方案
                fileElem.click();
            }
           
            // 我们的A标签的href属性值为"#",需要阻止浏览器的默认行为
            e.preventDefault();
        }, false);
 
        function handleFiles(files) {
            if (!files.length) {
                fileList.innerHTML = "<p>No files selected!</p>";
            } else {
                var list = document.createElement("ul");
                for (var i = 0; i < files.length; i++) {
                    var li = document.createElement("li");
                    list.appendChild(li);
 
                    var img = document.createElement("img");
                   
                    // 生成文件标示符,并将标示符指向img的src属性
                    img.src = window.URL.createObjectURL(files[i]);
                    img.height = 200;
                    img.onload = function(e) {
                     
                      // 释放文件标示符占用的内存
                        window.URL.revokeObjectURL(this.src);
                    }
                    li.appendChild(img);
 
                    var info = document.createElement("span");
                    info.innerHTML = files[i].name + ": " + files[i].size + " bytes" + ": " + files[i].type;
                    li.appendChild(info);
                }
                fileList.appendChild(list);
            }
        }
 
(4)、方法说明:
createObjectURL 
每次调用该方法都会为文件生成标识文件的唯一字符串,多次调用该方法即使参数是同一个文件也会生成不同的字符串。因此,我们需要释放文件标识所占用的内存,当页面被销毁时会自动释放,但是如果页面是动态生成的,我们通常会用脚本移除掉包含预览图的DOM,在移除的时候我们需要手动释放内存。但是官方推荐的做法是为图片绑定onload事件,在图片加载完成后释放内存。
 
revokeObjectURL
释放文件标示符占用的内存,通常在图片的onload事件处理程序中调用该方法
 
(5)、最后看一下DOM结构,img标签的src属性指向的是一个以blob开头的字符串
 
方式二: FileReader
(1)、先看一下效果图:
 
(2)、HTML代码如下:
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files);this.value='';">
<a href="#" id="fileSelect">Select some files</a> 
<div id="preview"></div>
 
(3)、JS代码如下:
    function handleFiles(files) {
            var previewEle = document.getElementById("preview");
            for (var i = 0; i < files.length; i++) {
                var file = files[i];
                var imageType = /image.*/;
 
                if (!file.type.match(imageType)) {
                    continue;
                }
 
                var img = document.createElement("img");
                img.classList.add("obj");
                img.file = file;
                img.width = '300';
 
                previewEle.appendChild(img);
 
                var reader = new FileReader();
                reader.onload = (function(aImg) {
                    return function(e) {
                        aImg.src = e.target.result;
                    };
                })(img);
                reader.readAsDataURL(file);
            }
        }
 
(4)、看一下DOM结构,img标签的src属性是图片的base64码:
 
原文地址:https://www.cnblogs.com/hellohuman/p/3917409.html