图片上传是一个普通不过的功能,而图片预览就是就是上传功能中必不可少的子功能了。在这之前,我曾经通过订阅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+(不支持滤镜)则使用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); };
以上就是本文的全部内容,希望对大家的学习有所帮助。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用