H5 多文件Input样式和上传(多次添加,随意删除,名称显示)

H5 多文件Input样式和上传(多次添加,随意删除,名称显示)

一、使用场景

  1. H5界面使用!!!Vue等其他前端都有很好的方式,不需要看这个
    • 需要多个文件上传时,原始的Input type=file 存在的问题有:
      1.必须一次性选择多个文件,如果遇到文件不在同一个文件夹就比较麻烦。
      2.第二次选择的文件会覆盖第一次的选择的文件。
      3.多个文件时不会显示文件名称,只会显示文件数量。
      4.选择完后不能随意删除,必须重新选择等等问题。

    • 所以如果遇到以上问题,是可以使用这个代码的

  2. 看样式
    • 没有文件选择时:在这里插入图片描述

    • 选择文件时:在这里插入图片描述


话不多说,直接上代码

二、代码实现

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();
 }

总结

  1. 原始button样式比较丑并且使用起来复杂,用这个方法样式好看、可以清楚的看到已选择的文件和数量,并且可以随意增删!
  2. 文件上传的代码也比较简单,可以自己添加和修改,还是比较方便的

如果需要图片预览和文件下载功能,可以看一下另一篇文章,实现多文件的预览和下载。

H5多文件Input样式及文件上传

🙉在小小的电脑上面敲呀敲呀敲,写短短的代码,埋小小的坑🙈

🙉在大大的电脑上面敲呀敲呀敲,写大大的代码,埋大大的坑🙈

🙉在特别大的电脑上面敲呀敲呀敲,写特别大的代码,埋特别大的坑🙈

🙉优秀的你肯定是一个不爱写Bug并且爱点赞关注的靓仔吧!🙈

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值