一、业界现状分析
有时候我们需要在上传图片之前为用户提供图片预览的功能,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://developer.mozilla.org/zh-CN/docs/Using_files_from_web_applications
时间: 2024-09-30 19:16:37