图片粘贴上传实现
图片上传 html demo
直接粘贴本地运行查看效果即可,有看不懂的直接喂给 deepseek 会解释的很清晰
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>粘贴图片上传示例 - 使用场景,粘贴桌面图片上传、粘贴word 文档中图片上传、直接截图上传等</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
}
.upload-area {
width: 100%;
height: 200px;
border: 2px dashed #ccc;
display: flex;
align-items: center;
justify-content: center;
color: #666;
font-size: 18px;
margin-bottom: 20px;
}
.file-list {
margin-top: 20px;
}
.file-item {
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ddd;
background-color: #f9f9f9;
}
.file-item.uploading {
background-color: #e0f7fa;
}
.file-item.done {
background-color: #e8f5e9;
}
.file-item.error {
background-color: #ffebee;
}
</style>
</head>
<body>
<h1>粘贴图片上传示例</h1>
<div class="upload-area">
请在此区域粘贴图片
</div>
<div class="file-list">
<h2>文件列表</h2>
<div id="file-list-container"></div>
</div>
<script>
// 模拟语言包
const t = (key) => {
const translations = {
'examination.pasteNoContent': '粘贴内容为空',
};
return translations[key] || key;
};
// 生成唯一 ID
const uuidv4 = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};
// 文件上传前的校验
const onBeforeUpload = async (file, { maxHeight, maxWidth, size, maxCount, t, fileList }) => {
if (fileList.length >= maxCount) {
alert(`最多只能上传 ${maxCount} 张图片`);
return false;
}
if (file.size > size) {
alert(`文件大小不能超过 ${size / 1024 / 1024}MB`);
return false;
}
return true;
};
// 模拟文件上传函数
const fileUpload = (file, { onSuccess, onError }) => {
setTimeout(() => {
if (Math.random() > 0.5) {
onSuccess({ url: 'https://example.com/uploaded-image.jpg' });
} else {
onError('上传失败,请重试');
}
}, 2000); // 模拟 2 秒上传时间
};
// 数据处理函数
const dataHandle = ({ file, fileList }) => {
return { file, fileList };
};
// 粘贴图片上传处理函数
const handelPasteImageUpload = async (event, {
t,
resource = { images: [] },
onStartUpload,
onUploadSuccess,
onUploadError,
imageUploadLimitConfig,
}) => {
const fileList = resource.images || [];
const clipboardData = event.clipboardData;
if (clipboardData) {
const items = clipboardData.items || [];
if (items.length <= 0) {
alert(t('examination.pasteNoContent'));
return;
}
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.type.indexOf('image') !== -1) {
event.preventDefault(); // 阻止默认行为
const originFileObj = item.getAsFile(); // 获取文件对象
// 构建文件数据对象
const fileDataObj = {
originFileObj,
uid: uuidv4(),
lastModified: originFileObj.lastModified,
name: originFileObj.name,
size: originFileObj.size,
type: originFileObj.type,
};
const { maxHeight, maxWidth, size, maxCount } = imageUploadLimitConfig;
// 文件上传前的校验
const flag = await onBeforeUpload(originFileObj, {
maxHeight,
maxWidth,
size: size.image,
maxCount: maxCount.image,
t,
fileList,
});
if (flag) {
const newFileList = [...fileList, fileDataObj].map((item) => {
if (item.uid === fileDataObj.uid) {
return { ...item, status: 'uploading' };
}
return item;
});
// 调用开始上传回调
onStartUpload(dataHandle({ file: fileDataObj, fileList: newFileList }));
// 模拟文件上传
fileUpload(originFileObj, {
onSuccess: (response) => {
const updatedFileList = newFileList.map((item) => {
if (item.uid === fileDataObj.uid) {
return { ...item, status: 'done', response };
}
return item;
});
onUploadSuccess(dataHandle({ file: fileDataObj, fileList: updatedFileList }));
},
onError: (error) => {
const updatedFileList = newFileList.map((item) => {
if (item.uid === fileDataObj.uid) {
return { ...item, status: 'error', response: error };
}
return item;
});
onUploadError(dataHandle({ file: fileDataObj, fileList: updatedFileList }));
},
});
}
}
}
}
};
// 初始化
document.addEventListener('paste', (event) => {
handelPasteImageUpload(event, {
t,
resource: { images: [] },
onStartUpload: (data) => {
console.log('开始上传:', data);
renderFileList(data.fileList);
},
onUploadSuccess: (data) => {
console.log('上传成功:', data);
renderFileList(data.fileList);
},
onUploadError: (data) => {
console.error('上传失败:', data);
renderFileList(data.fileList);
},
imageUploadLimitConfig: {
maxHeight: 1000,
maxWidth: 1000,
size: { image: 5 * 1024 * 1024 }, // 5MB
maxCount: { image: 10 },
},
});
});
// 渲染文件列表
const renderFileList = (fileList) => {
const container = document.getElementById('file-list-container');
container.innerHTML = fileList
.map(
(file) => `
<div class="file-item ${file.status}">
<strong>${file.name}</strong> - ${file.status}
${file.response ? `<br>响应: ${JSON.stringify(file.response)}` : ''}
</div>
`
)
.join('');
};
</script>
</body>
</html>