<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery多图上传插件</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<style>
.upload-container {
border: 2px dashed #ccc;
border-radius: 8px;
padding: 20px;
text-align: center;
background-color: #f9f9f9;
transition: all 0.3s;
margin-bottom: 20px;
}
.upload-container.dragover {
border-color: #007bff;
background-color: #e6f2ff;
}
.upload-btn {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: white;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.upload-btn:hover {
background-color: #0056b3;
}
.file-input {
display: none;
}
.preview-container {
display: flex;
flex-wrap: wrap;
margin-top: 15px;
gap: 10px;
}
.preview-item {
position: relative;
width: 100px;
height: 100px;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.preview-img {
width: 100%;
height: 100%;
object-fit: cover;
}
.preview-remove {
position: absolute;
top: 2px;
right: 2px;
background-color: rgba(255,0,0,0.7);
color: white;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
}
.progress-container {
margin-top: 10px;
height: 6px;
background-color: #f0f0f0;
border-radius: 3px;
overflow: hidden;
}
.progress-bar {
height: 100%;
background-color: #007bff;
width: 0%;
transition: width 0.3s;
}
.status-text {
margin-top: 5px;
font-size: 12px;
color: #666;
}
.upload-info {
margin-top: 10px;
font-size: 14px;
color: #666;
}
</style>
</head>
<body>
<h1>jQuery多图上传插件演示</h1>
<div class="demo-container">
<h3>上传示例1:最多上传3张图片</h3>
<div id="uploader1"></div>
<h3>上传示例2:最多上传5张图片</h3>
<div id="uploader2"></div>
</div>
<script>
(function($) {
// 默认配置
const defaults = {
maxFiles: 5,
uploadUrl: '/api/common/upload',
acceptedFiles: 'image/*',
fileSizeLimit: 5 * 1024 * 1024 // 5MB
};
// 插件定义
$.fn.up = function(callback, options) {
const settings = $.extend({}, defaults, options);
return this.each(function() {
const $container = $(this);
const files = [];
// 创建上传界面
const uploadHTML = `
<div class="upload-container">
<div class="upload-btn">选择图片</div>
<input type="file" class="file-input" multiple accept="${settings.acceptedFiles}">
<div class="upload-info">支持拖放上传,最多 ${settings.maxFiles} 张图片</div>
<div class="preview-container"></div>
<div class="progress-container">
<div class="progress-bar"></div>
</div>
<div class="status-text"></div>
</div>
`;
$container.html(uploadHTML);
const $uploadContainer = $container.find('.upload-container');
const $fileInput = $container.find('.file-input');
const $uploadBtn = $container.find('.upload-btn');
const $previewContainer = $container.find('.preview-container');
const $progressBar = $container.find('.progress-bar');
const $statusText = $container.find('.status-text');
// 点击上传按钮触发文件选择
$uploadBtn.on('click', function() {
$fileInput.click();
});
// 文件选择事件
$fileInput.on('change', function(e) {
handleFiles(e.target.files);
});
// 拖放功能
$uploadContainer.on('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
$uploadContainer.addClass('dragover');
});
$uploadContainer.on('dragleave', function(e) {
e.preventDefault();
e.stopPropagation();
$uploadContainer.removeClass('dragover');
});
$uploadContainer.on('drop', function(e) {
e.preventDefault();
e.stopPropagation();
$uploadContainer.removeClass('dragover');
const droppedFiles = e.originalEvent.dataTransfer.files;
handleFiles(droppedFiles);
});
// 处理选择的文件
function handleFiles(fileList) {
const newFiles = Array.from(fileList);
// 检查文件数量限制
if (files.length + newFiles.length > settings.maxFiles) {
alert(`最多只能上传 ${settings.maxFiles} 张图片`);
return;
}
// 处理每个文件
newFiles.forEach(file => {
// 检查文件类型
if (!file.type.match('image.*')) {
alert('只能上传图片文件');
return;
}
// 检查文件大小
if (file.size > settings.fileSizeLimit) {
alert(`文件 ${file.name} 大小超过限制`);
return;
}
// 添加到文件列表
files.push(file);
// 创建预览
const reader = new FileReader();
reader.onload = function(e) {
const previewItem = `
<div class="preview-item" data-filename="${file.name}">
<img src="${e.target.result}" class="preview-img">
<button class="preview-remove">×</button>
</div>
`;
$previewContainer.append(previewItem);
// 绑定删除事件
$previewContainer.find('.preview-remove').last().on('click', function() {
const $previewItem = $(this).closest('.preview-item');
const filename = $previewItem.data('filename');
// 从文件列表中移除
const index = files.findIndex(f => f.name === filename);
if (index > -1) {
files.splice(index, 1);
}
// 移除预览
$previewItem.remove();
});
};
reader.readAsDataURL(file);
});
// 自动开始上传
if (files.length > 0) {
uploadFiles();
}
}
// 上传文件
function uploadFiles() {
if (files.length === 0) return;
$statusText.text('准备上传...');
$progressBar.width('0%');
const formData = new FormData();
// 添加所有文件到FormData
files.forEach((file, index) => {
formData.append('files', file);
});
// 发送AJAX请求
$.ajax({
url: settings.uploadUrl,
type: 'POST',
data: formData,
processData: false,
contentType: false,
xhr: function() {
const xhr = new XMLHttpRequest();
// 上传进度事件
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
const percentComplete = (e.loaded / e.total) * 100;
$progressBar.width(percentComplete + '%');
$statusText.text(`上传中: ${Math.round(percentComplete)}%`);
}
}, false);
return xhr;
},
success: function(response) {
$statusText.text('上传成功!');
$progressBar.width('100%');
// 清空文件列表和预览
files.length = 0;
$previewContainer.empty();
// 调用回调函数
if (typeof callback === 'function') {
callback(response);
}
},
error: function(xhr, status, error) {
$statusText.text('上传失败: ' + error);
// 调用回调函数
if (typeof callback === 'function') {
callback({
code: 0,
msg: '上传失败: ' + error
});
}
}
});
}
});
};
})(jQuery);
// 使用示例
$(document).ready(function() {
// 第一个上传实例,最多3张图片
$('#uploader1').up(function(res) {
if (res.code == 1) {
console.log('上传成功:', res);
alert('上传成功!');
} else {
console.log('上传失败:', res.msg);
alert('上传失败: ' + res.msg);
}
}, {
maxFiles: 3
});
// 第二个上传实例,最多5张图片
$('#uploader2').up(function(res) {
if (res.code == 1) {
console.log('上传成功:', res);
alert('上传成功!');
} else {
console.log('上传失败:', res.msg);
alert('上传失败: ' + res.msg);
}
}, {
maxFiles: 5
});
});
</script>
</body>
</html>
发表评论 取消回复