参考文章: 拖拽外部文件进行读取-FileReader
个人学习笔记 | 前端原生API复盘 最近在做前端文件上传相关功能,需求里用到了拖拽上传+本地文件预览交互,特意把 HTML5 文件读取、原生拖拽事件相关知识点梳理一遍。把原理、事件说明和可运行实例都记录下来,方便后续自己复盘查阅,也分享给有同样需求的朋友,代码可以直接拿来使用。
一、核心技术:FileReader 与 File 对象
HTML5 新增的FileReader是实现本地文件读取的关键,无需后端参与,前端就能解析文件内容,搭配拖拽事件即可完成无上传预览。
1. FileList 对象
通过文件选择框(<input type="file">)或拖拽操作,能拿到FileList伪数组,每个元素是File对象,包含文件名称、大小、类型等信息。
2. FileReader 核心用法
- 实例化:
const reader = new FileReader() - 常用方法:
readAsDataURL()(读取文件为Base64地址,适合图片预览) - 核心事件:
onload(文件读取完成后触发) - 结果属性:
result(存储读取后的文件数据)
二、拖拽事件:实现页面文件拖拽
HTML5 支持原生拖拽交互,通过监听系列拖拽事件,就能捕获拖拽到页面的文件,核心事件如下:
| 事件名 | 作用对象 | 触发时机 |
|---|---|---|
ondragenter |
目标元素 | 拖拽元素进入目标区域 |
ondragover |
目标元素 | 拖拽元素停留在目标区域 |
ondrop |
目标元素 | 在目标区域松开鼠标,放置文件 |
⚠️ 关键注意:必须阻止ondragover和ondrop的默认行为,否则浏览器会直接打开文件,覆盖当前页面。
三、完整代码:拖拽文件并预览图片
下面是可直接复制运行的代码,实现“拖拽文件到方框内,自动预览图片”效果,样式简洁、逻辑清晰:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>HTML5拖拽文件读取预览</title>
<style>
/* 拖拽区域样式 */
.drop-box {
width: 400px;
height: 400px;
border: 2px dashed #666;
border-radius: 12px;
margin: 80px auto;
text-align: center;
line-height: 400px;
font-size: 24px;
color: #999;
transition: all 0.3s ease;
}
/* 拖拽进入时高亮 */
.drop-box.active {
border-color: #2196F3;
box-shadow: 0 0 15px rgba(33, 150, 243, 0.5);
}
/* 预览图片自适应 */
.drop-box img {
width: 100%;
height: 100%;
border-radius: 10px;
object-fit: cover;
}
</style>
</head>
<body>
<div class="drop-box">拖拽图片文件到此处</div>
<script>
// 获取拖拽容器
const dropBox = document.querySelector('.drop-box');
// 1. 阻止全局拖拽默认行为(防止页面跳转)
document.addEventListener('dragover', e => e.preventDefault());
document.addEventListener('drop', e => e.preventDefault());
// 2. 拖拽进入容器:高亮提示
dropBox.addEventListener('dragenter', () => {
dropBox.classList.add('active');
});
// 3. 拖拽离开容器:取消高亮
dropBox.addEventListener('dragleave', () => {
dropBox.classList.remove('active');
});
// 4. 放置文件:读取并预览
dropBox.addEventListener('drop', e => {
dropBox.classList.remove('active');
// 获取拖拽的第一个文件
const file = e.dataTransfer.files[0];
if (!file) return;
// 仅处理图片文件(可根据需求修改类型限制)
if (!file.type.startsWith('image/')) {
dropBox.innerText = '请拖拽图片文件!';
return;
}
// 实例化FileReader读取文件
const reader = new FileReader();
// 读取完成:渲染预览图
reader.onload = function (event) {
dropBox.innerHTML = `<img src="${event.target.result}" alt="预览图片">`;
};
// 以DataURL格式读取图片
reader.readAsDataURL(file);
});
</script>
</body>
</html>
四、关键避坑总结
必须阻止默认事件:dragover和drop事件不阻止默认行为,会导致浏览器直接打开文件;
异步读取特性:FileReader读取文件是异步的,必须在onload事件中获取结果;
文件类型限制:实际开发中需判断文件类型,避免读取非目标文件(如仅允许图片、PDF);
兼容性:现代浏览器均支持FileReader,无需兼容低版本 IE。