外观
轻松上传文件:通过拖拽和复制实现
通常我们上传文件是通过 <input type=file />
标签实现的,但是它是不支持拖拽和复制的。下面介绍两种额外的获取文件方法:
- 拖拽上传:直接拖拽设备文件放到指定元素上,获取文件。主要事件:
drop
。 - 复制上传:通过
Ctrl + V
和Ctrl + V
复制文件到指定元素上,获取文件。主要事件:paste
。
input
上传
先来看一下最基本的input
上传,我们通过监听change
事件,获取文件对象,然后通过FileReader
读取文件内容。
示例代码:
<input name="图片上传" type="file" accept="image/*" id="uploadImage"/>
const input = document.getElementById('uploadImage');
input.addEventListener('change', (event) => {
const files = event.target.files;
if (files.length > 0) {
console.log('处理file')
}
})
具体演示:
input file 上传演示
<input name="图片上传" type="file" accept="image/*" id="uploadImage"/>
<br/>
<img id="img"/>
const convertToBase64 = (file) => {
const reader = new FileReader();
reader.onload = (event) => {
const base64String = event.target.result;
const img = document.getElementById('img');
// 预览
img.src = base64String;
};
reader.readAsDataURL(file);
};
const isImageFile = (file) => {
return file.type.startsWith("image/");
};
const input = document.getElementById('uploadImage');
input.addEventListener('change', (event) => {
const files = event.target.files;
if (files.length > 0) {
const file = files[0];
const maxSize = 2 * 1024 * 1024;
if (file.size > maxSize) {
alert('图片大小超过限制,请重新选择!');
return;
}
if (isImageFile(file)) {
convertToBase64(file);
} else {
alert('请选择图片文件!');
}
}
})
img {
margin: 20px 0;
border-radius: 12px;
width: 200px;
height: 200px;
background-color: #ccc;
}
拖拽上传
拖拽上传是通过监听drop
事件,获取拖拽的文件对象,然后通过FileReader
读取文件内容。
示例代码:
<div id="dropUploadImage"> 将文件拖拽到此处 </div>
const dropElement = document.getElementById('dropUploadImage');
// 阻止默认行为
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropElement.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
dropElement.addEventListener('drop', (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
if (files && files.length > 0) {
console.log('处理file')
}
})
具体演示:
拖拽图片上传演示
<div id="dropUploadImage"> 将文件拖拽到此处 </div>
<img id="dropImg"/>
const convertToBase64 = (file) => {
const reader = new FileReader();
reader.onload = (event) => {
const base64String = event.target.result;
const img = document.getElementById('dropImg');
// 预览
img.src = base64String;
};
reader.readAsDataURL(file);
};
const isImageFile = (file) => {
return file.type.startsWith("image/");
};
const dropElement = document.getElementById('dropUploadImage');
// 阻止默认行为
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropElement.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
dropElement.addEventListener('drop', (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
if (files && files.length > 0) {
const file = files[0]
if (file) {
const maxSize = 2 * 1024 * 1024;
if (file.size > maxSize) {
alert('图片大小超过限制,请重新选择!');
return;
}
if (isImageFile(file)) {
convertToBase64(file);
} else {
alert('请选择图片文件!');
}
}
}
})
#dropUploadImage {
display: inline-block;
width: 200px;
height: 200px;
border: 1px dashed #ccc;
text-align: center;
line-height: 200px;
font-size: 24px;
color: #ccc;
box-sizing: border-box;
}
img {
vertical-align: bottom;
margin: 0 20px;
border-radius: 12px;
width: 200px;
height: 200px;
background-color: #ccc;
}
粘贴上传
粘贴上传是通过监听paste
事件,获取剪贴板的文件对象,然后通过FileReader
读取文件内容。
示例代码:
<input id="pasteUploadImage" type="text" />
const pasteUploadImage = document.getElementById('pasteUploadImage');
pasteUploadImage.addEventListener('paste', (event) => {
const items = event.clipboardData!.items;
for (let item of items) {
if (item.kind === "file" && item.type.startsWith("image/")) {
// 图片的话阻止默认
event.preventDefault();
const blob = item.getAsFile();
console.log('处理file')
}
}
})
具体演示:
复制图片粘贴上传演示
<input id="pasteUploadImage" type="text" />
<img id="pasteImg"/>
const pasteUploadImage = document.getElementById('pasteUploadImage');
const pasteImg = document.getElementById('pasteImg');
pasteUploadImage.addEventListener('paste', (event) => {
const items = event.clipboardData.items;
for (let item of items) {
if (item.kind === "file" && item.type.startsWith("image/")) {
// 图片的话阻止默认
event.preventDefault();
const blob = item.getAsFile();
const reader = new FileReader();
reader.onload = function (e) {
pasteImg.src = e.target.result;
};
reader.readAsDataURL(blob);
}
}
})
#pasteUploadImage {
outline: none;
border: 1px solid #ccc;
display: block;
width: 280px;
height: 32px;
line-height: 48px;
font-size: 16px;
color: #666;
padding: 0 12px;
border-radius: 12px;
}
img {
vertical-align: bottom;
margin: 20px 0;
border-radius: 12px;
width: 200px;
height: 200px;
background-color: #ccc;
}