JS魔法堂之实战:纯前端的图片预览
一、前言
图片上传是一个普通不过的功能,而图片预览就是就是上传功能中必不可少的子功能了。在这之前,我曾经通过订阅input[type=file]元素的 onchange事件,一旦更改路径则将图片上传至服务器,接着就获取图片路径并赋值到img元素上。先不管文件异步提交的解决方案,就是服务端清理那些 临时的预览图片已经增加不少工作量了。
偶然从MDN上找到纯前端图片预览的相关资料,经过整理后记录下来以便日后查阅。
二、准备功夫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). 浏览器支持
FF3.6+,Chrome7+,IE10+
三、准备功夫2──DXImageTransform.Microsoft.AlphaImageLoader滤镜
(1). 作用:主要作用是对图片进行透明处理(IE5.5~6并不支持透明的png)
(2). 样式中的使用方式
#preview{filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale,src="dummy.png");
}
(3). JS中的使用方式
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>
js片断:
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+(不支持滤镜)则使用FileReadervar 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作了安全方面的考虑,使得在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.createRangeColleciton() 获取真实地址,具体操作如下:
// 假设fileEl就是[type=file]元素
fileEl.select();
var filePath = document.selection.createRangeCollection()[0].htmlText;
六、20140902补充:使用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);
};
七、总结
好吧,现在妈妈再也不担心我的图片预览实现得太麻烦了!
如果觉得上面的使用方式不方便,可以访问https://github.com/fsjohnhuang/preview/blob/master/preview.js,我已经将其封装成工具函数了。
JS魔法堂之实战:纯前端的图片预览相关推荐
- 纯前端文档预览,还要支持所有主流格式,有这一篇就足够了
写在前面 纯前端的文档预览功能,是非常常见的需求,但就是这么简单的需求,难住了许多可爱的小伙伴们.别急,先访问一下解决方案,给你一个惊喜,再往下看: 文件在线预览DEMO 服务器文件预览DEMO 20 ...
- cropper.js 图像旋转问题_JavaScript开源良心插件,纯前端网页图片剪裁插件——cropperjs...
介绍 cropperjs是一款基于JavaScript的网页端图片裁剪插件,可能相对于图片预览来说,图片的裁剪使用场景貌似并不是很多,但是图片预览插件又要比裁剪插件容易找到,而且从实现难度上来说也不及 ...
- web安全:JS纯前端实现图片或文件安全的上传和下载功能
背景 在做前端开发的过程中,做过很多的项目,都会遇到图片预览和展示.一般的图片都是用于页面美化,信息解释说明的作用.但是在接触某些业务场景时,例如用户注册需要上传用户个人身份证照片,办理业务需要上传证 ...
- php 图片预览原理,JavaScript_纯JS实现的批量图片预览加载功能,1.实现原理直接见代码,需要一 - phpStudy...
纯JS实现的批量图片预览加载功能 1.实现原理直接见代码,需要一张转圈的小图片,需要预览的所有图片默认的位置全是这张小图片,滚轮滚到原图需要出现的位置时候,预览加载替换小图片.实现效果 复制代码 代码 ...
- 纯前端实现图片上传功能
纯前端实现图片上传功能,告别后端formData上传 使用ElementUI中的upload组件+腾讯云实现简单的图片上传功能 了解了upload的基本属性之后我们要开始上硬菜了 使用ElementU ...
- 在线浏览pdf doc html,前端实现在线预览pdf、word、xls、ppt等文件
1.前端实现pdf文件在线预览功能 方式一: 通过a标签href属性实现 pdf文件理论上可以在浏览器直接打开预览但是需要打开新页面.在仅仅是预览pdf文件且UI要求不高的情况下可以直接通过a标签hr ...
- 浅谈js本地图片预览
最近在工作中遇到一个问题,就是实现一个反馈页面,这个反馈页面的元素有反馈主题.反馈类型.反馈内容.反馈人联系电话以及反馈图片.前端将这些反馈的元素POST给后台提供的接口:实现这个工作的步骤就是:页面 ...
- 前端页面预览word_前端实现在线预览文档
前端实现在线预览文档 发布时间:2019-06-03 17:22, 浏览次数:529 <>前端实现在线预览文档 最近项目开发中需要实现在线预览Word,Excel,PowerPoint格式 ...
- 强大的图片预览组件Viewer.js
1. Viewer.js简介 Viewer.js 是一款强大的图片查看器.我们通过Viewer.js 在页面上添加强大的图片查看功能,同时,这款优秀的插件配置操作起来也非常的方便. Viewer. ...
最新文章
- 一个简单好用的Android Tab 设计与实现
- 了解 JavaScript (4)– 第一个 Web 应用程序
- C#字数统计(字母、数字、汉字、符号)
- Oracle 共享锁和排它锁、 DML和DDL锁、 for update 锁表的问题
- 模拟调频信号FM解调的matlab和C语言实现
- java多线程论文_Java5 多线程之入门篇-论文
- TX1在opencv中调用gstreamer解码海康IP摄像头
- Linux系统LVM增加新硬盘实现根文件系统扩容
- 扩展CheckBoxList实现选中绑定
- 关于silverlight主题皮肤(一)
- 【LeetCode】【字符串】题号:*539. 最小时间差
- java button 点击事件_android_button按钮onclick点击事件的几种写法
- steam授权_验号机器人正式上线,支持检验csgo账号、steam账号信息
- Orcad 16.6中批量修改网络名
- PHP基于微信小程序的医院预约挂号系统 uniapp 小程序
- 51单片机计算机实物焊接,51单片机实验DIY焊电源--串口详细步骤
- 前端-项目引入苹方字体
- mac macbook应用清单
- C语言简单的双人小游戏
- xshell rz传输文件立即失败解决方法
热门文章
- 订餐系统-第一个用NodeJs实现的项目
- 使用dx命令在cmd环境下执行的正确方法,我用的版本android4.4.2,jdk1.8
- 转Oracle性能参数—经典常用
- 苹果自动驾驶“排名垫底”,每1.1英里就发生一次脱离...
- C#版 - Leetcode 201. 数字范围按位与(bitwise AND) - 题解
- 第四篇、Python文件处理
- 记一次DRBD Unknown故障处理过程
- Tab选项卡界面(1)
- python中类的构成_Python中类型关系和继承关系实例详解
- python输出运行时间_分析python程序运行时间的几种方法