首页 > 代码库 > 文件上传之图片预览

文件上传之图片预览

一、业界现状分析
有时候我们需要在上传图片之前为用户提供图片预览的功能,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=http://www.mamicode.com/‘‘;"><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 =http://www.mamicode.com/ 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=http://www.mamicode.com/‘‘;"><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://developer.mozilla.org/zh-CN/docs/Using_files_from_web_applications