HTML结构
使用<input>
标签创建文件上传控件,并配置相关属性。
type="file"
accept
image/
表示所有图片)multiple
capture
capture="camera"
)示例代码:
<input type="file" id="upload" accept="image/" multiple> <img id="preview" src="#" alt="预览图" style="max-width: 300px;">
JavaScript处理逻辑
通过监听文件选择事件,读取文件并上传至服务器。
步骤 | 说明 |
---|---|
监听change 事件 |
当用户选择文件时触发 |
获取文件列表 | 通过event.target.files 获取选中的文件集合 |
预览图片 | 使用FileReader 将文件转为Base64 URL并显示在<img> 中 |
上传文件 | 通过FormData 封装文件,并用fetch 或XMLHttpRequest 发送到服务器 |
示例代码:
const uploadInput = document.getElementById('upload'); const previewImg = document.getElementById('preview'); // 监听文件选择 uploadInput.addEventListener('change', function(e) { const files = e.target.files; if (files.length === 0) return; // 未选择文件 const file = files[0]; // 仅处理第一个文件(可扩展为多文件) // 图片预览 const reader = new FileReader(); reader.onload = function(e) { previewImg.src = e.target.result; }; reader.readAsDataURL(file); // 上传文件(需后端接口支持) const formData = new FormData(); formData.append('image', file); fetch('/upload', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => console.log('上传成功:', data)) .catch(err => console.error('上传失败:', err)); });
图片预览优化
若需支持多文件预览,可动态生成预览区域。
uploadInput.addEventListener('change', function(e) {
const files = e.target.files;
const previewContainer = document.getElementById('preview-container');
previewContainer.innerHTML = ''; // 清空旧预览
Array.from(files).forEach(file => {
const reader = new FileReader();
reader.onload = function(e) {
const img = document.createElement('img');
img.src = e.target.result;
img.style.maxWidth = '100px';
previewContainer.appendChild(img);
};
reader.readAsDataURL(file);
});
});
样式与兼容性
-
隐藏原始控件:可通过CSS隐藏
<input>
,用自定义按钮触发点击事件。#upload { display: none; } #custom-btn { cursor: pointer; }
<button id="custom-btn">选择图片</button> <script> document.getElementById('custom-btn').addEventListener('click', () => { document.getElementById('upload').click(); }); </script>
-
兼容性:
FileReader
和FormData
在现代浏览器中均支持,低版本IE需降级处理。
常见问题与解答
问题1:如何限制上传文件的类型和大小?
if (file.size > 5 1024 1024) { // 超过5MB
alert('文件过大!');
return;
}
问题2:如何一次性上传多张图片?
- 设置
multiple
属性允许多选文件。 - 遍历
files
列表,分别处理每个文件:Array.from(files).forEach(file => { // 对每个文件执行预览或上传逻辑