html5-使用FileReader读取文件
昨天学习vue框架配置文件时,浏览了一个博客园的博主写的一篇关于html5的API–FileReader用于读取文件的操作博客。仔细想想,刚开始学vue框架时,也想使用FileReader将图片转成base64码,多方便,都不需要调用接口,后来vue的eslint老是报错–FileReader不存在,未定义之类,当时时间紧,没仔细检查原因,就不了了之了。现在重新使用FileReader。
FileReader
FileReader对象使用 File 或 Blob 对象指定要读取的文件或数据。
常用事件:
FileReader.onload
处理load事件。该事件在读取操作完成时触发。
常用方法:
FileReader.readAsDataURL()
读取Blob中的内容,返回data: URL格式的字符串
代码如下:
<section class="upload-outer-block upload-outer-box">
<section class="source">
<section class="upload-block">
<section class="el-upload el-upload--text">
<!--云图标-->
<section class="upload-dragger">
<i class="upload-icon"></i>
<section class="upload-text">
将文件拖到此处,或
<em>点击上传</em>
</section>
</section>
<!--上传元素-->
<input type="file" multiple class="hide" />
<!--提示文字-->
<section class="upload-tip">
只能上传jpg/png文件,且不超过500kb
</section>
<ul class="upload-list">
</ul>
</section>
</section>
</section>
</section>
.hide {
display: none;
}
a {
color: #409eff;
text-decoration: none;
}
/*最外层盒子离底部距离*/
.upload-outer-box {
margin-bottom: 24px;
}
/*最外层盒子边框*/
.upload-outer-block {
border: 1px solid #ebebeb;
border-radius: 3px;
transition: .2s;
width: 414px;
}
/*包含上传块的盒子*/
.upload-outer-block .source {
padding: 24px;
}
/*上传的盒子*/
.upload-outer-box .upload-block {
width: 360px;
}
/*drag start*/
.upload-dragger {
background-color: #fff;
border: 1px dashed #d9d9d9;
border-radius: 6px;
box-sizing: border-box;
width: 360px;
height: 180px;
text-align: center;
cursor: pointer;
position: relative;
overflow: hidden;
}
.upload-dragger:hover {
border-color: #409eff;
}
.upload-dragger .upload-icon {
font-size: 67px;
color: #c0c4cc;
margin: 40px 0 16px;
line-height: 50px;
display: inline-block;
}
/*上传操作文字*/
.upload-dragger .upload-text {
color: #606266;
font-size: 14px;
text-align: center;
}
.upload-dragger .upload-text em {
color: #409eff;
font-style: normal;
}
.upload-dragger.dragover {
background-color: rgba(32, 159, 255, .06);
border: 2px dashed #409eff;
}
/*drag end*/
/*上传显示图标*/
.upload-icon:before {
content: url(img/上传.png);
vertical-align: middle;
display: inline-block;
}
/*上传提示文字*/
.upload-tip {
font-size: 12px;
color: #606266;
margin-top: 7px;
text-align: center;
}
/*上传成功后,显示图片的列表*/
.upload-list {
margin: 0;
padding: 0;
list-style: none;
}
/*公共li样式*/
.upload-list li {
overflow: hidden;
z-index: 0;
background-color: #fff;
border: 1px solid #c0ccda;
border-radius: 6px;
box-sizing: border-box;
margin-top: 10px;
position: relative;
padding: 10px 10px 10px 90px;
height: 92px;
}
/*上传图片样式*/
.upload-list .upload-img {
width: 70px;
height: 70px;
margin-left: -80px;
float: left;
box-shadow: 0px 1px 1px 1px #AAA3A3;
}
.upload-list .upload-img:hover {
box-shadow: 0px 1px 1px 2px #83ABD2;
}
.upload-list .big {
z-index: 2;
max-width: none;
max-height: none;
box-shadow: 2px 2px 10px 2px #666;
}
/*图片名称*/
.upload-list .upload-img-name {
line-height: 70px;
margin-top: 0;
color: #606266;
display: block;
}
.upload-list .upload-img-name:hover {
color: #409eff;
cursor: pointer;
}
/*图片右上角绿色背景*/
.upload-list .right-corner {
/*绝对样式,相对于父元素*/
position: absolute;
right: -17px;
top: -7px;
width: 46px;
height: 26px;
background: #13ce66;
text-align: center;
transform: rotate(45deg);
box-shadow: 0 1px 1px #ccc;
}
/*图片右上角是否读取成功标志*/
.upload-list .right-corner .correct-icon {
font-size: 12px;
margin-top: 12px;
color: #fff;
display: inline-block;
margin-top: 9px;
}
.upload-list .right-corner .correct-icon:before {
content: url('./img/correct.png');
}
/*图片右上角是否读取失败标志*/
.upload-list .wrong-icon {
font-size: 12px;
margin-top: 12px;
margin-top: 9px;
display: none;
top: -8px;
right: 2px;
transform: rotate(0deg);
position: absolute;
cursor: pointer;
}
.upload-list .wrong-icon:before {
content: url('./img/wrong.png');
}
.upload-list li i {
transform: rotate(-45deg);
}
init()
function init() {
if (!(window.FileReader && window.File && window.FileList && window.Blob)) {
alert('您的浏览器不支持fileReader')
return false
}
fileReaderHandler()
}
function fileReaderHandler() {
// 上传框
var dragSection = document.querySelector('.upload-dragger')
// 上传框所有样式
var dragSectionClassList = dragSection.classList
// 获取文件的file
var inputFile = document.querySelector('[type=file]')
// 显示文件的ul
var ul = document.querySelector('.upload-list')
// 点击drag块添加文件
dragSection.onclick = function (e) {
// 模拟点击事件
var evt = new MouseEvent('click', {
bubbles: false,
cancelable: true,
view: window
})
inputFile.dispatchEvent(evt)
}
// 拖拽到drag块添加文件
dragSection.ondragenter = function (e) {
if (!dragSectionClassList.contains('dragover')) {
dragSectionClassList.add('dragover')
}
return false
}
dragSection.ondragover = function (e) {
preventDefault(e)
if (!dragSectionClassList.contains('dragover')) {
dragSectionClassList.add('dragover')
}
}
dragSection.ondragleave = function (e) {
if (dragSectionClassList.contains('dragover')) {
dragSectionClassList.remove('dragover')
}
}
dragSection.ondrop = function (e) {
preventDefault(e)
if (dragSectionClassList.contains('dragover')) {
dragSectionClassList.remove('dragover')
}
var files = e.dataTransfer.files
if (files.length) {
// 验证文件
checkFiles(files, ul)
}
}
// 监听添加文件的事件
inputFile.onchange = function (e) {
var files = this.files
if (files.length) {
// 验证文件
checkFiles(files, ul)
}
}
}
// 检验并读取文件
function checkFiles(files, ul) {
var html = '',
i = 0
var loadFile = function () {
// 读取所有文件完毕
if (i >= files.length) {
ul.innerHTML = html
return false
}
var file = files[i]
var fileSize = Math.ceil(file.size / 1024)
// 验证图片格式
if (!/image\/\w+/.test(file.type) || fileSize > 500) {
alert('只能上传jpg/png文件,且不超过500kb')
return false
}
var reader = new FileReader(file)
// 读取文件操作
reader.onload = function (e) {
html +=
'<li onmouseover=\'onCornerChange(this, ".right-corner", ".wrong-icon")\' onmouseleave=\'onCornerChange(this, ".wrong-icon", ".right-corner")\'><img src=' +
e.target.result + ' class=\'upload-img\'></img>' +
'<a class=\'upload-img-name\'><span>' + file.name +
'</span></a><label class=\'right-corner\'><i class=\'correct-icon\'></i></label><i index=' +
i + ' class=\'wrong-icon\' onclick="onDeleteImg(this.index)"></i></li>'
i++
// 读取下一个文件
loadFile()
}
reader.readAsDataURL(file)
}
loadFile()
}
// 图片右上角图标改变
function onCornerChange(li, className1, className2) {
li.querySelector(className1).style.display = 'none'
li.querySelector(className2).style.display = 'block'
}
// 删除照片
function onDeleteImg(index) {
if (confirm('是否删除已加载的图片?')) {
var ul = document.querySelector('.upload-list')
ul.removeChild(ul.childNodes.item(index))
}
}
// 阻止事件的默认行为
function preventDefault(e) {
if (e.preventDefault) {
e.preventDefault()
} else {
e.returnValue = false
}
}
暂时只用到了上面提到的方法和事件,对于事件,如果有需要,可以自行添加;读取图片只需要FileReader.readAsDataURL()即可。
代码中警告和确认框我偷懒了,就用浏览器自带的,而且,做出了只能读取图片的限制!这仅仅是一个静态页面展示FileReader读取文件的方法,后期将图片放大、缩小、上传文件,都做出来,并最后封装成组件。
演示如下
小结
- FileReader可将图片转base64,且API方法丰富。
- 可将上传图片(文件)模块封装成组件