readAsDataURL
readAsDataURL 会将文件内容进行 base64 编码后进行输出
<input type="file" id="file" />
document.getElementById('file').addEventListener(
'change',
(fileChoosed) => {
const reader = new FileReader()
reader.readAsDataURL(fileChoosed.target.files[0])
reader.onload = function (readResult) {
console.log('load complete', readResult.target.result)
}
}
)
上述代码执行之后在控制台输出 base64 编码字符串。由于媒体文件的 src 属性,可以通过采用网络地址或者 base64 的方式显示,因此我们可以利用 readAsDataURL 实现对图片的预览。
<input type="file" id="file" />
<img src="" id="imgPreview" />
document.querySelector('#file').addEventListener(
'change',
(fileChoosed) => {
const reader = new FileReader()
reader.readAsDataURL(fileChoosed.target.files[0])
reader.onload = (readResult) => {
document.querySelector('#imgPreview').src = readResult.target.result
}
}
)
注意
- 一个 FileReader 实例只能同时读取一个文件,例如
<input type="file" name="file" id="file" multiple>
<img src="" alt="" srcset="" id="img">
const file = document.getElementById('file')
const img = document.getElementById('img')
file.onchange = (fileChoosed) => {
const reader = new FileReader()
for (const fileChoosedItem of fileChoosed.target.files) {
reader.readAsDataURL(fileChoosedItem)
reader.onload = (readResult) => {
console.log(readResult.target.result)
}
}
}
上述代码只能读取第一个,同步读取第二个会抛出异常
修改删除代码,使之可以正常运行,例如
- 情况一
file.onchange = (fileChoosed) => {
for (const fileChoosedItem of fileChoosed.target.files) {
const reader = new FileReader()
reader.readAsDataURL(fileChoosedItem)
reader.onload = (readResult) => {
console.log(readResult.target.result)
}
}
}
上述代码每次执行时,在块级作用域内会重新声明一个新的 FileReader 实例,进行读取文件操作,不进行干扰。
- 情况二
file.onchange = (fileChoosed) => {
const reader = new FileReader()
for (const fileChoosedItem of fileChoosed.target.files) {
setTimeout(() => {
reader.readAsDataURL(fileChoosedItem)
})
}
reader.onload = (readResult) => {
console.log(readResult.target.result)
}
}
上述代码执行时,将同步读取变为异步读取,不会阻塞当前 readAsDataURL,可正常运行
- 情况三
file.onchange = (fileChoosed) => {
const reader = new FileReader()
for (const fileChoosedItem of fileChoosed.target.files) {
setTimeout(() => {
reader.readAsDataURL(fileChoosedItem)
})
}
reader.onload = (readResult) => {
console.log(readResult.target.result)
}
}