H5 多文件Input样式和上传(多次添加,随意删除,名称显示)
一、使用场景
- H5界面使用!!!Vue等其他前端都有很好的方式,不需要看这个。
-
需要多个文件上传时,原始的Input type=file 存在的问题有:
1.必须一次性选择多个文件,如果遇到文件不在同一个文件夹就比较麻烦。
2.第二次选择的文件会覆盖第一次的选择的文件。
3.多个文件时不会显示文件名称,只会显示文件数量。
4.选择完后不能随意删除,必须重新选择等等问题。 -
所以如果遇到以上问题,是可以使用这个代码的。
-
- 看样式
-
没有文件选择时:
-
选择文件时:
-
话不多说,直接上代码
二、代码实现
H5及JS代码(整个页面代码,可以直接复制到HTML5界面打开看)
代码里有button的样式,文件名显示、删除的js,以及文件提交到后端的代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传测试</title>
<style type="text/css">
.file {
position: relative;
display: inline-block;
background: #D0EEFF;
border: 1px solid #99D3F5;
border-radius: 4px;
padding: 4px 12px;
overflow: hidden;
color: #1E88C7;
text-decoration: none;
text-indent: 0;
line-height: 20px;
}
.file input {
position: absolute;
font-size: 100px;
right: 0;
top: 0;
opacity: 0;
}
.file:hover {
background: #AADFFD;
border-color: #78C3F3;
color: #004974;
text-decoration: none;
}
</style>
</head>
<body>
<div>
<a href="javascript:;" class="file">文件上传
<input type="file" name="clientInfoFile" id="filesInput" multiple
accept="image/jpeg, image/jpg, image/png, application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document">
</a>
<a onclick="save()" class="file">保存
<input type="button">
</a>
<div>
<span id="totalFileSpan" class="hidden"></span>
<div id="selectedFiles"></div>
</div>
</div>
<!--如果使用$.ajax,请在这里更换上自己的jquery.js或者使用网上的juqey.js-->
<!--<script src="path/jquery.js"></script>-->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
//全局已选择文件列表
var fileList = new Map();
// 获取input框的dom元素
var filesInput = document.getElementById('filesInput');
//获取展示文件的input框元素
var selectedFilesDiv = document.getElementById('selectedFiles');
//给input框添加监听时间
filesInput.addEventListener('change', updateSelectedFilesList);
// 当选择文件时的监听时间
function updateSelectedFilesList(event) {
Array.from(event.target.files).forEach((file) => {
//判断是否有重名文件,有的话直接返回并弹出提示
for (var key of fileList.keys()) {
if(key.firstElementChild.title == file.name){
// $.modal.alertWarning('禁止重复上传文件');
return;
}
}
//创建显示文件信息的组件div
var fileItem = document.createElement('div');
//设置名称长度,过长给省略掉
var fileName = file.name.length > 50 ? file.name.substring(0, 50) + '...' : file.name;
//设置样式
fileItem.className = 'file-item';
//名称
fileItem.innerHTML = '<span title="' + file.name + '">' + fileName + '</span>'
//创建删除按钮及样式
var deleteBtn = document.createElement('a');
deleteBtn.style = "margin-left : 20px";
deleteBtn.innerHTML = '删除';
//不加href没有下划线,这个可以自定义加不加
deleteBtn.href = "#"
//给删除按钮添加click事件
deleteBtn.addEventListener('click', function() {
fileList.delete(fileItem)
fileItem.remove();
updateTotalFileSpan();
});
//把按钮添加到文件名称后面
fileItem.appendChild(deleteBtn);
//再把所有组件添加到展示文件的组件下
selectedFilesDiv.appendChild(fileItem);
//给fileList赋值,保存文件信息
fileList.set(fileItem,file)
});
updateTotalFileSpan();
}
//更改文件数量
function updateTotalFileSpan() {
//获取显示文件数量的标签组件
let totalFileSpan = document.getElementById("totalFileSpan")
if(fileList.size > 0){
let fileSizeValue = "已选择"+ fileList.size + "个文件";
totalFileSpan.classList.remove("hidden")
totalFileSpan.textContent = fileSizeValue
}else {
totalFileSpan.classList.add("hidden");
totalFileSpan.textContent = ""
}
console.log(fileList)
}
function save() {
//创建ajax传输参数所需的FormData
//其他参数也可以在这里添加,直接使用formData.append("参数名","参数值")就行
let formData = new FormData();
//获取文件列表
let files = [];
for (let value of fileList.values()) {
files.push(value);
}
for (var i = 0; i < files.length; i++) {
//有需求可以在这里对每个文件做处理,没需求可以直接添加
formData.append('files', files[i]); // 将每个文件添加到数组参数中
}
//这里我用的是Jquery.js 中的 $.ajax请求,也可以更改为原生的new XMLHttpRequest()请求方式
$.ajax({
cache: true,
type: "POST",
url: prefix + "/save", //prefix是前缀地址,这里可以换成自己的地址
contentType: false, //必须要加, 不设置 contentType 属性,让浏览器自动识别
processData: false, //必须要加, 不处理发送的数据,让浏览器自动处理
data: formData,//上面定义的数据
async: true,
beforeSend: function () {
debugger
// 提交之前方法,一般加遮盖层
// $.modal.loading("正在处理中,请稍后...");
},
error : function(request) {
// 提交返回失败方法
// $.modal.closeLoading();
// $.modal.alertError("系统错误");
},
success: function(data) {
// 提交成功方法
// $.modal.closeLoading();
// $.operate.successCallback(data);
}
});
}
</script>
</body>
</html>
JAVA后端接收文件
@RequestMapping(value = "/save",method = RequestMethod.POST)
@ResponseBody
public AjaxResult save(@RequestParam(value = "files", required = false) List<MultipartFile> files, @RequestParam("params", required = false) String params) {
//AjaxResult是返回类,可以换成自己需要的返回类,比如JSONResult,或者任意类型,拿到前端处理就行
try {
//文件处理,方法自己添加
doFiles();
//其他参数处理,方法自己添加
doParams();
} catch (Exception e) {
return AjaxResult.error("保存异常!");
}
return AjaxResult.success();
}
总结
- 原始button样式比较丑并且使用起来复杂,用这个方法样式好看、可以清楚的看到已选择的文件和数量,并且可以随意增删!
- 文件上传的代码也比较简单,可以自己添加和修改,还是比较方便的!
如果需要图片预览和文件下载功能,可以看一下另一篇文章,实现多文件的预览和下载。
🙉在小小的电脑上面敲呀敲呀敲,写短短的代码,埋小小的坑🙈
🙉在大大的电脑上面敲呀敲呀敲,写大大的代码,埋大大的坑🙈
🙉在特别大的电脑上面敲呀敲呀敲,写特别大的代码,埋特别大的坑🙈
🙉优秀的你肯定是一个不爱写Bug并且爱点赞关注的靓仔吧!🙈