文章目录
- 前言
- 一、选择本地文件
- 1.设计一个上传文件按钮
- 2.FileReader读取文件内容
- 二、使用拖拽方式
- 1.设计一个拖拽容器
- 2.拖拽文件的相关事件回调
- 三、使用粘贴方式
- 1.设计一个粘贴容器
- 2.paste事件回调
- 四、总结
前言
前端无法像app一样直接操作本地文件,对本地文件的操作和上传,通常使用以下三种方式:
- 通过input type = file 选择本地文件上传,这是最常见的方式
- 通过拖拽的方式把文件拖过来
- 在编辑框里面复制黏贴,这种方式常见于上传图片。
一、选择本地文件
1.设计一个上传文件按钮
通过input type = file 选择本地文件上传,通常会自定义一个按钮,然后盖在上面,因为type=file的input不容易改变样式。
这里使用label做样式覆盖,label 元素不会向用户呈现任何特殊效果。不过,它为鼠标用户改进了可用性。如果在 label 元素内点击文本,就会触发此控件。就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上。
注意:label中的for属性应与input元素的id一致
<form id="form">
<label for="submit">
<div class="lBut">
<span>选择文件</span>
</div>
</label>
<input id="submit" type="file" />
</form>
#submit {
display: none;
}
.lBut {
width: 87px;
height: 24px;
font-size: 14px;
line-height: 24px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 4px;
margin-left: 28px;
transition: all 0.5s;
white-space: nowrap;
background-color: #409eff;
color: white;
border: 1px solid #409eff;
}
而通过表单选择的文件无法直接获取文件真实存放路径,文件里面内容也无法查看。formData格式的文件可以作为接口参数传给后台。
const inputFile = document.getElementById("submit");
const form = document.getElementById("form");
inputFile.addEventListener("change", function () {
let formData = new FormData(form);
console.log("formData :>> ", formData);
console.log("inputFile.value :>> ", inputFile.value);
});
2.FileReader读取文件内容
当选择文件后,触发input的change事件,在change的回调方法中初始化一个fileReader对象,fileReader有一个方法readAsDataURL可以读取文件并转为base64格式。在fileReader读取文件后触发onload回调方法,在回调方法中获取文件的结果,并创建一个img元素把结果作为src属性值,展示在页面上。
js代码如下:
const inputFile = document.getElementById("submit");
const form = document.getElementById("form");
inputFile.addEventListener("change", function () {
let file = inputFile.files[0];
if (!file) return;
console.log("file :>> ", file);
// 读取文件并转化为base64格式
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = function () {
console.log("fileReader :>> ", fileReader);
if (/^image\/[jpeg|png|gif]/.test(file.type)) {
let img = document.createElement("img");
img.src = fileReader.result;
img.style.width = "500px";
document.body.append(img);
}
};
});
二、使用拖拽方式
1.设计一个拖拽容器
<body>
<div id="container">drag your image here</div>
</body>
<style>
#container {
width: 500px;
height: 500px;
border: 1px solid #dfdfdf;
margin: 0 auto;
text-align: center;
vertical-align: middle;
}
</style>
2.拖拽文件的相关事件回调
容器的dragover事件和drop事件的默认行为是打开新页面展示,需要阻止默认行为
在drop事件回调中,获取拖拽的文件,数据存储在event.dataTransfer.files中,然后就可以调用fileReader.readAsDataURL或添加到formData中了
const container = document.getElementById("container");
container.addEventListener("dragover", function (event) {
// 浏览器默认行为是打开新页面展示,需要阻止默认行为
event.preventDefault();
});
container.addEventListener("drop", function (event) {
console.log("event :>> ", event);
event.preventDefault(); // 阻止默认的点击事件执行
let file = event.dataTransfer.files[0];
console.log("file :>> ", file);
if (!file) return;
showImg(file);
});
const showImg = (file) => {
// 读取文件并转化为base64格式
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = function () {
if (/^image\/[jpeg|png|gif]/.test(file.type)) {
let img = document.createElement("img");
img.src = fileReader.result;
img.style.width = "500px";
container.append(img);
}
};
};
三、使用粘贴方式
1.设计一个粘贴容器
粘贴通常在一个编辑框操作,比如把div的contenteditable设置为true
<div id="container" contenteditable="true">paste your image here</div>
2.paste事件回调
粘贴的数据在event.clipboardData.files中,在容器的paste获取,代码如下:
const container = document.getElementById("container");
container.addEventListener("paste", function () {
event.preventDefault();
let file = event.clipboardData.files[0];
console.log("file :>> ", file);
if (!file) return;
showImg(file);
});
const showImg = (file) => {
// 读取文件并转化为base64格式
let fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = function () {
if (/^image\/[jpeg|png|gif]/.test(file.type)) {
let img = document.createElement("img");
img.src = fileReader.result;
img.style.width = "500px";
container.append(img);
}
};
};
四、总结
文件的上传常见有三种方式:选择文件、拖拽和粘贴。选择文件通常使用表单,文件的数据在form.files中,form为表单元素;拖拽的方式,文件的数据在drop事件的event.dataTransfer.files中;粘贴的方式,文件的数据在paste事件的event.clipboardData.files中;在获取上传文件的数据后,使用fileReader来读取文件数据,展示在页面上,或者添加到formData上,通过接口传递给后台。