首先需要了解几个api
FileReader
FileReader主要用于将文件内容读入内存,通过一系列异步接口,可以在主线程中访问本地文件。
<table> <tr> <th>方法定义</th> <th>描述</th> </tr> <tr> <td>abort():void</td> <td>终止文件读取操作</td> </tr> <tr> <td>readAsArrayBuffer(file):void</td> <td>异步按字节读取文件内容,结果用ArrayBuffer对象表示</td> </tr> <tr> <td>readAsBinaryString(file):void</td> <td>异步按字节读取文件内容,结果为文件的二进制串</td> </tr> <tr> <td>readAsDataURL(file):void</td> <td>异步读取文件内容,结果用data:url的字符串形式表示</td> </tr> <tr> <td>readAsText(file,encoding):void</td> <td>异步按字符读取文件内容,结果用字符串形式表示</td> </tr> </table>
事件
<table> <thead> <tr> <th>事件名称</th> <th>描述</th> </tr> </thead> <tbody> <tr> <td>onabort</td> <td>当读取操作被中止时调用</td> </tr> <tr> <td>onerror</td> <td>当读取操作发生错误时调用</td> </tr> <tr> <td>onload</td> <td>当读取操作成功完成时调用</td> </tr> <tr> <td>onloadend</td> <td>当读取操作完成时调用,不管是成功还是失败</td> </tr> <tr> <td>onloadstart</td> <td>当读取操作将要开始之前调用</td> </tr> <tr> <td>onprogress</td> <td>在读取数据过程中周期性调用</td> </tr> </tbody> </table>
画布API
- 创建画布 var canvas = document.createElement('canvas');
- 在画布上绘图的环境。var context = canvas.getContext('2d')
- 填充一张图片到画布上 context.drawImage(img,0,0,canvas.width,img.height/ratio);
- 将画布转为blob canvas.toBolob(callback)
下载图片
html5中在a链接中加入了download
属性时,会强制触发下载操作,且自动命名文件为download
属性的值。我们定义一个鼠标事件并初始化,然后在a链接上绑定事件,并触发这个鼠标事件,等于手动点击了这个a标签,起到了下载的功能
模拟创建鼠标事件对象的方法
- 新建一个鼠标事件 let event = document.createEvent('MouseEvents')
- 初始化鼠标事件 event.initMouseEvent('click',false,false,window,0,0,0,0,0,false,false,false,false,0,null)
- 在节点上绑定事件,并触发这个事件 element.dispatchEvent(event)
创建鼠标事件对象的方法createEvent('MouseEvents'),返回的对象的方法initMouseEvent(),接收15个信息:
1. type(字符串):事件类型如“click”;
2. bubble(布尔值):是否冒泡;
3. cancelable(布尔值):是否可取消;
4. view(AbstractView):与事件关联的视图,一般为document.defaultView;
5. detail(整数):一般为0,一般只有事件处理程序使用;
6. screenX(整数):事件相对于屏幕的X坐标;
7. screenY(整数);
8. clientX(整数):事件相对于视口的X坐标;
9. clientY(整数);
10. ctrlKey(布尔值):是否按下了Ctrl键,默认为false;
11. altKey(布尔值);
12. shiftKey(布尔值);
13. metaKey(布尔值);
14. button(整数):表示按下了哪个鼠标键,默认为0;
15. relatedTarget(对象):表示与事件相关的对象。一般只有在模拟mouseover与mouseout时使用。
另外,建议使用构造函数MouseEvent
来初始化创建一个事件
var evt = new MouseEvent("click", {
bubbles: true,
cancelable: true,
view: window
});
模拟创建键盘事件
- 新建一个键盘事件 var event = document.createEvent("KeyboardEvent");
- 初始化这个键盘事件 event.initKeyboardEvent("keydown",true,true,document.defaultView,"a",0,"Shift",0);
- 在元素上模拟触发这个键盘事件 element.dispatchEvent(event);
event.initKeyboardEvent
接受以下参数:
typeArg(字符串):要触发的事件类型,可选(keydown, keypress, or keyup)
canBubbleArg(布尔值):表示事件是否应该冒泡;
cancelableArg(布尔值):是否可以取消;
viewArg(AbstractView):与事件关联的视图。一般为document.defaultView;
keyArg(布尔值):表示按下的键的键码;
locationArg(整数):表示按下哪里的键。0为主键盘;1为左;2为右;3为数字键盘;4为虚拟键盘;5为手柄;
modifiersListArg(字符串):空格分隔的修改键列表,如“shift”;
repeatArg(整数):在一行中按下了多少次这个键;
文件上传
FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据 let formData = new FormData();
- 添加字段 formData.append("username", "Groucho")
base64转File
function base64ToFile(base64,filename) {
var arr = base64.split(','),mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),n=bstr.length,u8arr=new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr],filename,{type:mime})
}
base64转Blob
function base64ToBlob(base64){
var arr = base64.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime });
}
XMLHttpRequest
- 获取一个XMLHttpRequest对象 var xhr = new XMLHttpRequest();
- 初始化一个请求 xhr.open('POST',url)
- 设置一个请求头 xhr.setRequestHeader(),必须在open之后,send之前
- 发送数据 xhr.send(data)
- 当readyState属性发生变化时调用 xhr.onreadystatechange
参考文档
一个例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="file" name="filename" id="fileInput" multiple>
<div id="box"></div>
<script>
var fileInput = document.getElementById('fileInput')
// 上传监听
fileInput.onchange = function(e){
let files = e.target.files;
for(let i=0;i<files.length;i++){
fileReader(files[i])
}
}
//将上传file处理为reader和图片
function fileReader(file){
let reader = new FileReader(),img = document.createElement('img');
reader.onload = function(){
img.src = reader.result;
}
img.onload = function(){
imageHandler(img,{
filename:file.name
})
}
reader.readAsDataURL(file)
}
//图片的处理(压缩、裁切、下载、上传)
function imageHandler(img,options){
var canvas = document.createElement('canvas');
canvas.width = img.width < 300 ? img.width : 300;
let ratio = img.width/img.height;
canvas.height = canvas.width/ratio;
var context = canvas.getContext('2d')
context.drawImage(img,0,0,canvas.width,canvas.width/ratio);
let base64 = canvas.toDataURL('image/jpeg',0.9)
let image = document.createElement('img')
image.src = base64
image.onload = function(){
document.getElementById('box').appendChild(image)
}
//下载
//download(base64,options.filename)
// 画布导出为blob并上传
// canvas.toBlob(function(blob){
// console.log(blob)
// var formData = new FormData();
// formData.append('filename',blob,options.filename)
// httpPost('https://beihaoyun.gophper.com/upload/file',formData)
// })
//base64转化为blob并上传
// var blob = base64ToBlob(base64)
// var formData = new FormData();
// formData.append('filename',blob,options.filename)
// httpPost('https://beihaoyun.gophper.com/upload/file',formData)
// base64转化为图片并上传
// var formData = new FormData();
// formData.append('filename',base64ToFile(base64,options.filename))
// httpPost("https://beihaoyun.gophper.com/upload/file",formData)
}
//base64转file
function base64ToFile(base64,filename) {
var arr = base64.split(','),mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),n=bstr.length,u8arr=new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr],filename,{type:mime})
}
//base64转blob
function base64ToBlob(base64){
var arr = base64.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime });
}
//ajax
function httpPost(url,params,options) {
console.log(params)
var xhr = new XMLHttpRequest();
xhr.open('POST',url)
xhr.send(params)
}
//下载图片
function download(base64,filename){
let a = document.createElement('a');
a.href = base64
a.download = filename+'.jpg';
let event = document.createEvent('MouseEvent')
event.initMouseEvent('click',false,false,window,0,0,0,0,0,false,false,false,false,0,null)
var evt = new MouseEvent("click", {
bubbles: true,
cancelable: true,
view: window
});
a.dispatchEvent(evt)
}
</script>
</body>
</html>