您好,欢迎访问一九零五行业门户网

js实现纯前端的图片预览_javascript技巧

图片上传是一个普通不过的功能,而图片预览就是就是上传功能中必不可少的子功能了。在这之前,我曾经通过订阅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片断:

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+(不支持滤镜)则使用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作了安全方面的考虑,使得在input[type=file]元素上通过value、outerhtml和getattribute的方式都无法获取用户所选文件的真实地址,只能获取到 c:\fakepath\文件名称 。因此假如使用ie11,但文本模式却设置为10以下,那就没木有办法实现图片预览了。
解决办法1──在head标签下加入这句: 。这样就可以告诉ie,默认使用当前ie的最高版本解析、渲染网页了。
解决办法2──采用 document.selection.createrangecolleciton() 获取真实地址,具体操作如下:
// 假设fileel就是[type=file]元素fileel.select();var filepath = document.selection.createrangecollection()[0].htmltext;
五、补充:使用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);};
以上就是本文的全部内容,希望对大家的学习有所帮助。
其它类似信息

推荐信息