引入
当使用<input type=file>
上传图片文件时,如何在上传到服务器之前,在本地进行预览?
FileReader 对象
FileReader对象允许Web应用程序异步读取用户计算机上的文件。使用new
创建一个FileReader实例对象:
let fileReader = new FileReader();
属性
-
error
:在读取时发生的错误 -
readyState
:fileReader当前状态 -
result
:读取到的文件内容,只有在读取操作完成后有效
方法
-
abort()
:终止读取操作 -
readAsDateURL()
:读取文件中的内容,读取完成后调用onloadend
方法,结果result
中包含一个data:URL
格式的字符串表示文件内容(针对图片就是base64格式的字符串)
事件处理程序
-
onabort
:读取被终止时被调用 -
onerror
:读取错误时调用 -
onload
:读取成功时调用 -
onloadend
:读取完成时调用,无论成功失败, 在onload
或onerror
后调用 -
onloadstart
:读取开始前调用 -
onprogress
:读取过程中周期调用、
兼容性
使用FileReader对象预览图片
- 在
<input>
的onchange
事件中获取上传的图片对象 - 使用
<input>
的event.target.files
获取上传对象的类数组对象,每一项的name
属性对应文件名 -
<input>
中增加multiple
属性,上传多个文件 - 创建
FileReader
对象,并通过readAsDateURL()
方法,传入要预览的文件对象,在onload
回调函数中对FileReader
对象的result
进行处理
代码:
预览多张图片
<body>
<label><input type="file" id="file" multiple></label>
<div id="preview" class="preview">
<img id="img" src="default.png">
</div>
</body>
<script>
'use strict';
let input = document.querySelector('#file'),
wrapper = document.querySelector('#preview'),
img = document.querySelector('#img');
function preview(files) {
Object.keys(files).forEach(function (file) {
let fileReader = new FileReader();
fileReader.readAsDataURL(files[file]);
fileReader.onload = function () {
img.src = fileReader.result;
img.title = files[file].name;
};
})
}
input.onchange = function (e) {
let files = e.target.files;
preview(files)
};
</script>
拖拽预览
不通过点击事件而是通过将图片拖拽到指定区域实现预览。
在拖放过程中会触发的事件:
-
在源元素上触发的事件(需要设置
draggable
属性)-
ondragstart
:开始拖动时触发 -
ondrag
:拖动时触发 -
ondragend
:拖动完成时触发
-
-
释放时触发的事件
-
ondragenter
:进入容器范围时触发 -
ondragover
:拖动时触发(触发间隔350毫秒) -
ondragleave
:离开容器范围时触发 -
ondrop
:拖动过程中,释放鼠标按键时触发
-
显然这里需要使用的是 ondrop
事件,但是需要注意,使用ondrop
事件需要阻止浏览器默认行为,否则不会触发
document.addEventListener("drop", function(e) { //释放
e.preventDefault();
});
document.addEventListener("dragenter", function(e) { //拖进
e.preventDefault();
});
document.addEventListener("dragleave", function(e) { //拖离
e.preventDefault();
});
document.addEventListener("dragover", function(e) { //拖来拖去
e.preventDefault();
});
然后在 ondrop
事件中触发上面的函数就可以实现图片预览了。注意,`input
的 onchange
事件获取文件对象是 e.target.files
,而 drop
事件则是 e.dataTransfer.files
window.URL.createObjectURL()
也可以通过这个方法来实现图片的预览
URL.createObjectURL()
静态方法会创建一个 DOMString
,这个新的URL 对象表示指定的 File
对象或 Blob
对象。
在每次调用createObjectURL()
方法时,都会创建一个新的URL
对象,即使你已经用相同的对象作为参数创建过。当不再需要这些URL
对象时,每个对象必须通过调用URL.revokeObjectURL()
方法来释放。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。
// 使用 createObjectURL
function preview2(files) {
Object.keys(files).forEach(function(file) {
img.src = window.URL.createObjectURL(files[file]);
})
}
区别
由于 URL.createObjectURL()
是浏览器自身的接口,貌似性能会更好一点
并且可能比fileReader对IE的兼容性好一些,问题少一些?
不过可以二者选择使用吧,多一个选择不是坏事
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。