加载本地文件
要加载本地文件,需要使用<input>
标签:
<input type="file" id="file" multiple>
如上:
- type: 必须为
file
。 - multiple: 用于同时加载多个文件。
这样就会生成一个选择文件按钮,其右侧显示未选择任何文件。
点击选择文件,即可弹出一个文件选择窗口。
同时该元素还接收拖放,拖动多个文件到选择文件即可。
在<input>
外添加一个<div>
,该组件同样会支持拖放,其行为就像是<input>
的一部分。
选择文件后,会触发<input>
的change
事件:
var files = []
window.onload = function(e) {
var f = document.getElementById("file")
f.onchange = function() {
files = this.files
}
}
如上,为<input>
注册change
事件,当有文件拖放到<input>
上时,该事件会触发并接收到拖放的文件内容。
由于支持多文件,故而接收到的文件是一个数组,每个元素都是一个文件。
读取文件内容
当拿到文件后,要使用FileReader
来读取文件的内容:
var loadCount = 0 // 已读取文件数量
// 读取单个文件
var loadAFile = function(file) {
var reader = new FileReader()
reader.onload = function(e) {
var r = this.result
loadCount++
if (loadCount == files.length) {
console.log('读取完毕')
}
}
reader.readAsText(file, 'GB2312') // 以文本形式读取
}
for (var i = 0; i < files.length; i++) {
loadAFile(files[i])
}
如上:
- 使用
FileReader.readAsText()
来以文本形式读取文件,其第二个参数可传入编码。除了文本形式,还可以ArrayBuffer/BinaryString/DataURL
形式读取。具体可参考文档。 FileReader.readAsText()
会触发FileReader
的onload
事件,但这是异步的。故而上面使用for
来读取所有文件时,很可能for
循环已经结束了,第0个文件的onload
才刚触发。因此上面对读取单个文件封装了函数,这样会隔离作用域。使用一个单独的变量loadCount
来记录已读取文件数量,从而可判断是否所有文件都读取完毕。