js预览及上传图片

使用浏览器File API, 即可读取本地图片,

使用FileReader即可预览图片,

使用FormData以及XMLHttpRequest对象即可上传图片

选择图片

首先要有个input

1
2
<label for="input">选择图片</label>
<input type="file" id="input" hidden accept="image/png, image/jpeg, image/gif, image/jpg" onchange="onSelectFile(this.files)">

其中multiple可以多选, PC端(需要按shift键), 及IOS是没问题的, 但安卓机普遍仍然是单选的.

accept 限定了所选文件的类型, 上面的写法表示只能选择图片. 当然也可以使用accept="image/*", 不过这种写法有可能会让文件选择框出现的慢一点

然后可以在onSelectFile回调中获取FileList对象

1
2
3
4
5
onSelectFile (files) {
console.log(files)
// FileList 类似结构如下
// {0: File, length: 1}
}

要注意的是FileList是个对象, 虽然有length属性, 但不是数组, 不能使用forEach等方法来遍历

一个文件, 就files[0]来获取; 多个文件的话, 老老实实用for循环就好了

另外, 还可以选择文件夹,
<input type="file" directory webkitdirectory/>
不过只在谷歌及火狐有效

文件上传

1
2
3
4
5
6
7
8
9
10
11
12
var formData = new FormData()
// file 为从FileList获取的File对象
formData.append('file', file)
// 兼容性 IE7+
var xhr = new XMLHttpRequest()
xhr.open("post", uploadUrl, true)
xhr.send(formData)
xhr.onload = () => {
// upload success
}

上面的写法是一个请求上传一张图片, 如果多张图片, for循环就好了.

但多张图片的话, 如何知道何时全部上传成功?

一个笨方法是使用定时器, 定时检查已上传成功的图片数量是否与已选择的图片数量相等, 如果相等, 说明全部上传成功.

1
2
3
4
5
6
let int = setInterval(() => {
if (this.uploadedList.length == this.fileList.length) {
this.$vux.loading.hide()
clearInterval(int)
}
}, 300)

如果想知道上传进度, 可以监听XMLHttpRequest.upload属性的progress方法

1
2
3
4
5
6
7
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
var percentComplete = Math.round(event.loaded * 100 / event.total)
// 输出的是百分比
console.log(percentComplete)
}
}

文件预览

1
2
3
4
5
6
7
8
let reader = new FileReader(),
file = files[index]
reader.readAsDataURL(file)
reader.onload = (e) => {
// e.target.result 就是读取的base64形式的图片地址, 可以放到img的src属性中, 即可在本地见面查看所选的图片
// <img src="${e.target.result}"/>
}

参考资料

MDN

zhangxinxu

Fork me on GitHub