在阅读
ajax与axios
【ajax中FileReader】的时候,遇到一个专题,就是这个题目,在web应用程序中一般会有哪些场景会使用文件?
- 发送和接受二进制文件
- 提交表单和上传文件
[]1
中有- 访问被选择的文件 (两种方式)
- 获取被选择文件的信息 (获取name,size,type(minetype))
- 隐藏file input元素 (两种方式,1用js 2用label+css)
- 使用拖放来选择文件
本篇大量参考MDN资料
我们一个一个看
2.1 发送和接受二进制文件
先来看发送
var oReq = new XMLHttpRequest();
oReq.open("POST", url, true);
oReq.onload = function (oEvent) {
// 上传完成后.
};
var bb = new BlobBuilder(); // 需要合适的前缀: window.MozBlobBuilder 或者 window.WebKitBlobBuilder
bb.append('abc123');
// 这里不可以用Blob构造函数,因为Blob构造只接受ArrayBuffer,ArrayBufferView,Blob,DOMString
// new Blob([])
oReq.send(bb.getBlob('text/plain'));
注意:XMLHttpRequest对象的
send方法
已被增强,可以通过简单的传入一个ArrayBuffer
,Blob
, 或者File
对象来发送二进制数据.
【了解】再来看接受,对于日常开发,拿到二进制数据一般很难会去操作它,都是展示数据
var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";
// 这里告诉浏览器,通过处理为arraybuffer,当然这里可以设置为Blob
oReq.onload = function (oEvent) {
var arrayBuffer = oReq.response; // 注意:不是oReq.responseText
if (arrayBuffer) {
var byteArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteArray.byteLength; i++) {
// 对数组中的每个字节进行操作
}
}
};
oReq.send(null);
2.2 访问被选择的文件
两种方式:
- onsubmit事件,给form元素设置
- onchange事件,给input元素设置
<form action="register.php" method="post" enctype="multipart/form-data"
onsubmit="AJAXSubmit(this); return false;">
</form>
<input type="file" id="input" multiple onchange="handleFiles(this.files)">
之后,各自事件中就可以访问到File对象了,就不说了
2.3 使用拖放来选择文件
let dropbox;
dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
看看各个回调函数如何处理
function dragenter(e) {
e.stopPropagation();
e.preventDefault();
}
function dragover(e) {
e.stopPropagation();
e.preventDefault();
}
dragenter和dragover都不需要处理额外内容,让默认处理和冒泡消失,重点在于drop
function drop(e) {
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
// 拿到files了,就可以后续的处理了
// 反观拖拽其实很简单,浏览器把大多数事情都做了
handleFiles(files);
}
拿到了文件,之后我们来看一个例子:显示用户选择的图片的缩略图
function handleFiles(files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /^image//;
if (!imageType.test(file.type)) {
continue;
}
var img = document.createElement("img");
img.classList.add("obj");
// 添加class,常见的可能是下面的方式(覆盖)
// img.className = 'obj'
img.file = file;
preview.appendChild(img); // 假设"preview"就是用来显示内容的div
var reader = new FileReader();
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
}
}
首先,需要明白几点:
- 1略缩图实现关键在于reader.readAsDataURL,将File文件转化为
data:
URL,从而压缩了图片 - 2向img上挂载了file属性,从而以后可以方便拿到原File文件
- 3为什么不先将src挂载到img上再append到容器中呢?其实都是一样的,图片加载是异步的
先读到这里,下面是使用对象 URL
上面代码有一个
document.createElement
很常见吧,但是它返回的是什么呢?Element还有这里提到了拖拽,上次一个boss问我如何实现拖拽模板创建相应内容?我没答上来,这里研究研究
2.3.1 Element
Element
是一个通用性非常强的基类,所有Document
对象下的对象都继承自它。这个接口描述了所有相同种类的元素所普遍具有的方法和属性。一些接口继承自Element
并且增加了一些额外功能的接口描述了具体的行为。例如,HTMLElement
接口是所有 HTML 元素的基本接口,而SVGElement
接口是所有 SVG 元素的基础。大多数功能是在这个类的更深层级(hierarchy)的接口中被进一步制定的。
2.3.2 拖拽
概述文档:HTML 拖放 API
专题文档:拖拽操作