纯前端图片预览:FileReader与IE滤镜实现方案
本文详解如何在纯前端实现图片预览功能。针对现代浏览器,利用HTML5 FileReader的readAsDataURL方法生成Data URI;针对IE5.5至9,采用DXImageTransform.Microsoft.AlphaImageLoader滤镜进行降级处理。同时解决IE11安全限制导致的fakepath问题,并介绍使用window.URL.createObjectURL优化大图片性能的方案。
纯前端图片预览方案概述
图片上传是常见功能,而图片预览则是上传流程中不可或缺的一环。以往的做法是监听input[type=file]的onchange事件,一旦路径改变便立即将文件上传至服务器,随后获取返回的图片路径并赋值给img元素。即便不考虑异步提交文件的复杂性,服务端清理这些临时预览图片也增加了额外的工作负担。
偶然在MDN文档中发现了纯前端实现图片预览的相关资料,经整理后记录如下,供日后查阅参考。
FileReader对象详解
一、准备工作1:FileReader对象
FileReader是HTML5引入的新特性,专门用于读取Blob和File类型的数据。其具体用法如下:
(1)构造方式
var fr = new FileReader(); (2)属性
readyState:类型为unsigned short,表示FileReader实例的当前状态(EMPTY——0,尚未加载任何数据;LOADING——1,数据正在加载;DONE——2,已完成全部读取请求),该属性只读。
result:表示读取到的文件内容,该属性只读。
error:类型为DOMError,表示在读取文件过程中发生的错误,该属性只读。
(3)方法
abort():中止读取操作,并将readyState设置为DONE。若在未执行读取操作时调用此方法,将抛出DOM_FILE_ABORT_ERR异常。
readAsArrayBuffer(Blob blob):读取数据,result属性将被设置为ArrayBuffer类型。
readAsText(Blob blob [, encoding='utf-8']):读取数据,result属性将被设置为String类型。
readAsBinaryString(Blob blob):读取数据,result属性将被设置为原始二进制数据。
readAsDataURL(Blob blob):读取数据,result属性将被设置为Data URI Scheme形式(具体可参考《JS魔法堂:Data URI Scheme介绍》)。
(4)事件
onload:读取数据成功后触发。
onerror:读取数据时抛出异常时触发。
onloadstart:读取数据前触发。
onloadend:读取数据后触发,会在onload或onerror之后触发。
onabort:中止读取后触发。
onprogress:读取过程中周期性触发。
(5)浏览器支持情况
Firefox 3.6+,Chrome 7+,IE 10+
IE滤镜AlphaImageLoader应用
二、准备工作2:DXImageTransform.Microsoft.AlphaImageLoader滤镜
(1)作用:主要用于对图片进行透明处理(注:IE5.5至6版本并不支持透明的PNG格式)。
(2)在CSS样式中的使用方式
#preview{
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src="dummy.png");
}
(3)在JavaScript中的使用方式
var preview = document.getElementById('preview');
preview.style.filter = preview.currentStyle.filter + ";progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src='dummy.png')";
preview.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src="dummy1.png";
(4)属性说明
enabled:可选项,用于设置滤镜是否激活。取值范围为true(默认值)或false。
sizingMethod:可选项,用于设置滤镜作用的图片在容器边界内的显示方式。取值范围包括crop(剪切图片以适应容器尺寸)、image(默认值,增大或缩小容器尺寸以适应图片尺寸)以及scale(缩放图片以适应容器尺寸)。
src:必填项,使用绝对或相对URL指向背景图片。当URL为用户计算机本地地址时有效;但若img元素的src直接指向用户计算机本地地址,则会抛出“不允许访问本地文件系统”的异常。
图片预览功能实现代码
三、具体实现方案
接下来,我们将利用FileReader的readAsDataURL方法获取Data URI Scheme来实现图片预览功能;对于IE5.5至9版本,则使用滤镜DXImageTransform.Microsoft.AlphaImageLoader进行降级处理。
HTML片段示例:
<style type="text/css">
#preview{
width: 100px;
height: 100px;
}
</style>
<!--[if lte IE 9]>
<style type="text/css">
#preview{
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);
}
</style>
<![endif]-->
<input type="file" onchange="showPreview(this);"/>
<div id="preview">
</div>
JavaScript片段示例:
var preview = function(el){
var pv = document.getElementById("preview");
// IE5.5~9使用滤镜
if (pv.filters && typeof(pv.filters.item) === 'function'){
pv.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = el.value;
}
else{
// 其他浏览器和IE10+(不支持滤镜)则使用FileReader
var fr = new FileReader();
fr.onload = function(evt){
var pvImg = new Image();
pvImg.style.width = pv.offsetWidth + 'px';
pvImg.style.height = pv.offsetHeight + 'px';
pvImg.src = evt.target.result;
pv.removeChild(0);
pv.appendChild(pvImg);
};
fr.readAsDataURL(el.files[0]);
}
};
IE11兼容性问题与解决
四、常见坑点与解决
由于IE11出于安全考虑,使得在input[type=file]元素上通过value、outerHTML和getAttribute等方式无法获取用户所选文件的真实地址,只能获取到形如 C:\fakepath\文件名称 的路径。因此,如果使用的是IE11但文档模式设置为10以下版本,则无法实现图片预览功能。
解决办法1:在head标签下加入以下代码: <meta http-equiv="X-UA-Compatible" content="IE=Edge"> 。这样可以告知IE浏览器默认使用当前IE的最高版本来解析和渲染网页。
解决办法2:采用 document.selection.createRangeCollection() 获取真实地址,具体操作步骤如下:
// 假设fileEl就是[type=file]元素
fileEl.select();
var filePath = document.selection.createRangeCollection()[0].htmlText;
createObjectURL性能优化方案
五、补充方案:使用window.URL.createObjectURL替代FileReader
通过FileReader的readAsDataURL方法获取的Data URI Scheme会生成一串很长的base64字符串。若图片较大,字符串长度会更长,当页面发生reflow(重排)时会导致性能下降。解决方案如下:
1. 对预览用的img标签使用绝对定位,使其脱离正常文档流,从而与文档的其他元素无关,这样在页面发生reflow时不会影响性能。
2. 采用 window.URL.createObjectURL(Blob blob) 生成数据链接。
var createObjectURL = function(blob){
return window[window.webkitURL ? 'webkitURL' : 'URL']['createObjectURL'](blob);
};
注意: window.URL.createObjectURL 生成的数据链接是独占内存的,因此若不再使用,需要调用 window.URL.revokeObjectURL(DOMString objUrl) 来释放内存。在刷新页面时,系统也会自动释放相关内容。
var resolveObjectURL = function(blob){
window[window.webkitURL ? 'webkitURL' : 'URL']['revokeObjectURL'](blob);
};
以上就是本文的全部内容,希望对大家的学习有所帮助。
Mock.js 拦截失效或数据格式错误的常见原因及排查
2026-11-05 10:11:59
Java和JavaScript名字像但没关系:辨析Java、JavaWeb与JS
2026-11-04 09:30:54
CodePen、JSFiddle与RunJS对比:哪款JS在线运行工具更适合你?
2026-11-03 16:46:57
JS 统计图渲染空白或报错怎么排查?常见问题解决指南
2026-11-03 09:49:40
flv.js 常见报错 MediaError 与解码失败排查指南
2026-11-02 10:29:29
