2023年6月21日发(作者:)
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 URIScheme介绍》)(4).事件onload:读取数据成功后触发onerror:读取数据时抛异常时触发onloadstart:读取数据前触发onloadend:读取数据后触发,在onload或onerror后触发onabort:中⽌读取后触发onprogress:读取过程中周期性触发(5). 浏览器⽀持FF3.6+,Chrome7+,IE10+
⼆、准备功夫2──mageLoader滤镜 (1). 作⽤:主要作⽤是对图⽚进⾏透明处理(IE5.5~6并不⽀持透明的png)(2). 样式中的使⽤⽅式#preview{ filter: progid:mageLoader(sizingMethod=scale,src="");} (3). JS中的使⽤⽅式var preview = mentById('preview'); = + ";progid:mageLoader(sizingMethod=scale,src='')";("mageLoader").src="";(4). 属性enabled:可选项,设置滤镜是否激活。值范围true(默认),falsesizingMethod:可选项,设置滤镜作⽤的图⽚在容器边界内的显⽰⽅式,值范围crop(剪切图⽚以适应容器尺⼨),image(默认值,增⼤或缩⼩容器尺⼨以适应图⽚的尺⼨),scale(缩放图⽚以适应容器尺⼨)src:必填项,使⽤绝对或相对URL指向背景图⽚。当URL为⽤户计算机本地地址时有效, ⽽img元素的src为⽤户计算机本地地址时会抛不允许访问本地⽂件系统的异常。 三、实现 接下来我们就利⽤FileReader的readAsDataURL来获取Data URI Scheme来实现图⽚预览的功能,⽽IE5.5~9我们就使⽤滤镜mageLoader来作降级处理。html⽚断:
js⽚断:var preview = function(el){ var pv = mentById("preview"); // IE5.5~9使⽤滤镜 if (s && typeof() === 'function'){ ("mageLoader").src = ; } else{ // 其他浏览器和IE10+(不⽀持滤镜)则使⽤FileReader var fr = new FileReader(); = function(evt){ var pvImg = new Image(); = Width + 'px'; = Height + 'px'; = ; Child(0); Child(pvImg); }; DataURL([0]); }};四、坑 由于IE11作了安全⽅⾯的考虑,使得在input[type=file]元素上通过value、outerHTML和getAttribute的⽅式都⽆法获取⽤户所选⽂件的真实地址,只能获取到 C:fakepath⽂件名称 。因此假如使⽤IE11,但⽂本模式却设置为10以下,那就没⽊有办法实现图⽚预览了。解决办法1──在head标签下加⼊这句: 。这样就可以告诉IE,默认使⽤当前IE的最⾼版本解析、渲染⽹页了。解决办法2──采⽤ RangeColleciton() 获取真实地址,具体操作如下:// 假设fileEl就是[type=file]元素();var filePath = RangeCollection()[0].htmlText;五、补充:使⽤ObjectURL代替FileReader
通过FileReader的readAsDataURL⽅法获取的Data URI Scheme会⽣成⼀串很长的base64字符串,若图⽚较⼤那么字符串则更长,若页⾯出现reflow时则会导致性能下降。解决⽅案如下: 1. 预览的img标签使⽤绝对定位,从⽽脱离正常⽂档流,那么就与⽂档的其他元素⽆关了,⽽reflow时则不会影响性能。 2. 采⽤ ObjectURL(Blob blob) ⽣成数据链接。var createObjectURL = function(blob){ return window[URL ? 'webkitURL' : 'URL']['createObjectURL'](blob);};注意: ObjectURL ⽣成的数据链接是独占内存的,因此若不时⽤时需要调⽤ObjectURL(DOMString objUrl) 来释放内存。在刷新页⾯时,也会⾃动释放内容。var resolveObjectURL = function(blob){ window[URL ? 'webkitURL' : 'URL']['revokeObjectURL'](blob);};以上就是本⽂的全部内容,希望对⼤家的学习有所帮助。
2023年6月21日发(作者:)
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 URIScheme介绍》)(4).事件onload:读取数据成功后触发onerror:读取数据时抛异常时触发onloadstart:读取数据前触发onloadend:读取数据后触发,在onload或onerror后触发onabort:中⽌读取后触发onprogress:读取过程中周期性触发(5). 浏览器⽀持FF3.6+,Chrome7+,IE10+
⼆、准备功夫2──mageLoader滤镜 (1). 作⽤:主要作⽤是对图⽚进⾏透明处理(IE5.5~6并不⽀持透明的png)(2). 样式中的使⽤⽅式#preview{ filter: progid:mageLoader(sizingMethod=scale,src="");} (3). JS中的使⽤⽅式var preview = mentById('preview'); = + ";progid:mageLoader(sizingMethod=scale,src='')";("mageLoader").src="";(4). 属性enabled:可选项,设置滤镜是否激活。值范围true(默认),falsesizingMethod:可选项,设置滤镜作⽤的图⽚在容器边界内的显⽰⽅式,值范围crop(剪切图⽚以适应容器尺⼨),image(默认值,增⼤或缩⼩容器尺⼨以适应图⽚的尺⼨),scale(缩放图⽚以适应容器尺⼨)src:必填项,使⽤绝对或相对URL指向背景图⽚。当URL为⽤户计算机本地地址时有效, ⽽img元素的src为⽤户计算机本地地址时会抛不允许访问本地⽂件系统的异常。 三、实现 接下来我们就利⽤FileReader的readAsDataURL来获取Data URI Scheme来实现图⽚预览的功能,⽽IE5.5~9我们就使⽤滤镜mageLoader来作降级处理。html⽚断:
js⽚断:var preview = function(el){ var pv = mentById("preview"); // IE5.5~9使⽤滤镜 if (s && typeof() === 'function'){ ("mageLoader").src = ; } else{ // 其他浏览器和IE10+(不⽀持滤镜)则使⽤FileReader var fr = new FileReader(); = function(evt){ var pvImg = new Image(); = Width + 'px'; = Height + 'px'; = ; Child(0); Child(pvImg); }; DataURL([0]); }};四、坑 由于IE11作了安全⽅⾯的考虑,使得在input[type=file]元素上通过value、outerHTML和getAttribute的⽅式都⽆法获取⽤户所选⽂件的真实地址,只能获取到 C:fakepath⽂件名称 。因此假如使⽤IE11,但⽂本模式却设置为10以下,那就没⽊有办法实现图⽚预览了。解决办法1──在head标签下加⼊这句: 。这样就可以告诉IE,默认使⽤当前IE的最⾼版本解析、渲染⽹页了。解决办法2──采⽤ RangeColleciton() 获取真实地址,具体操作如下:// 假设fileEl就是[type=file]元素();var filePath = RangeCollection()[0].htmlText;五、补充:使⽤ObjectURL代替FileReader
通过FileReader的readAsDataURL⽅法获取的Data URI Scheme会⽣成⼀串很长的base64字符串,若图⽚较⼤那么字符串则更长,若页⾯出现reflow时则会导致性能下降。解决⽅案如下: 1. 预览的img标签使⽤绝对定位,从⽽脱离正常⽂档流,那么就与⽂档的其他元素⽆关了,⽽reflow时则不会影响性能。 2. 采⽤ ObjectURL(Blob blob) ⽣成数据链接。var createObjectURL = function(blob){ return window[URL ? 'webkitURL' : 'URL']['createObjectURL'](blob);};注意: ObjectURL ⽣成的数据链接是独占内存的,因此若不时⽤时需要调⽤ObjectURL(DOMString objUrl) 来释放内存。在刷新页⾯时,也会⾃动释放内容。var resolveObjectURL = function(blob){ window[URL ? 'webkitURL' : 'URL']['revokeObjectURL'](blob);};以上就是本⽂的全部内容,希望对⼤家的学习有所帮助。
发布评论