基于layui.upload.js 拖拽文件/文件夹上传下载

本文介绍了如何利用layui的upload.js扩展实现前端拖拽上传文件和文件夹的功能。通过js代码示例、页面使用说明及CSS文件配置,详细展示了上传效果。总结中提到的关键点包括上传文件夹的处理、异步下载、上传分片、进度条和滚动条等技术细节。
摘要由CSDN通过智能技术生成

layui.upload.js 拖拽文件/文件夹上传下载

前言

项目需求完成文件上传,可以拖拽上传文件/文件夹,基于layui的upload.js增强完成该需求

js代码

layui的引入和使用就不说了,懂的都懂,不懂去学习一下,废话不多说,直接上代码.基于upload.js自定义uploadFile.js用于实现需求功能

/**
 * author: wz
 * referenceAddress:文件,文件夹上传
 */
layui.define(["layer", "upload",'element','table'], function (e) {
   
    "use strict";
    var $ = layui.$, layer = layui.layer, upload = layui.upload,element=layui.element,table=layui.table,
        tableArr=[],datas=[],model={
   },unfinishedList=[],beingList=[],timer=null,beingCount=10,beingFlag=false,timerTable=null,keepTime=0;
    //配置server token
    var conf = JSON.parse(localStorage.conf);
    var server = conf.file.server;
    var token = conf.file.token;
    function renderFile(option) {
   
        var uploadInst=upload.render({
   
            elem: '#' + option.id,
            auto: option.auto||false,
            accept: option.accept,
            acceptMime: option.acceptMime,
            exts: option.exts,
            size: option.size||0,
            multiple: option.multiple||true,
            number: option.number||0,
            choose:function (obj) {
   
                    var loadingIndex = layer.load(2, {
    //icon支持传入0-2
                        shade: [0.5, 'gray'], //0.5透明度的灰色背景
                        content: '读取文件...',
                        success: function (layero) {
   
                        }
                    });
                    obj.preview(function (index, file) {
   
                        loadingIndex="";
                        layer.closeAll();
                        var fileUuid=uuid();
                        uploadServer(file,fileUuid,"0",file.webkitRelativePath,option);
                    });
                    setTimeout(function () {
   
                        if(loadingIndex){
   
                            layer.closeAll();
                            layer.msg("上传类型错误,请检查!", {
   icon: 5});
                        }
                    },20000);
            }
        });
        selectEvent(option.id);
    }

    function selectEvent(id) {
   
        $('#' + id).bind("dragover",function (e) {
   
            $(this).css("background","#e9f5fe");
        })
        $('#' + id).bind("dragleave",function (e) {
   
            $(this).css("background","");
        })
        $('#' + id).bind("mouseover",function (e) {
   
            $(this).css("background","#e9f5fe");
        })
        $('#' + id).bind("mouseout",function (e) {
   
            $(this).css("background","");
        })
    }

    //上传中转站
    function uploadServer(file,fileUuid,type,path,option,serialNumber) {
   
        var parentId=option.parentId;
        if(type=='0'){
   //文件上传
            tableData(file,fileUuid,option.parentId,option.nodeId,"0");
        }else {
   //文件夹上传
            if(path){
   
                var split=path.split("/");
                for (var i = 0; i < split.length; i++) {
   
                    if(i<=split.length-2){
   
                        parentId=folderLoading(split[i],parentId,option.nodeId,serialNumber);
                    }else {
   
                        tableData(file,fileUuid,parentId,option.nodeId,"1");
                    }
                }
            }
        }
        unfinishedList.push({
   
            file:file,//文件对象
            type:type,//文件上传
            path:path,//文件路径
            uuid:fileUuid,//唯一标识
            parentId:parentId
        });
        if(timer==null){
   
            timer=setInterval(function (d) {
   
                    if(unfinishedList.length>0){
   
                        if(beingList.length<beingCount){
   //控制同时上传个数
                            var diff=beingCount-beingList.length;
                            for (let i = 0; i <diff ; i++) {
   
                                if(unfinishedList.length>i){
   
                                    beingList.push(unfinishedList[i].uuid);
                                    uploadDone(option,unfinishedList[i].file,unfinishedList[i].uuid,unfinishedList[i].parentId);
                                }
                            }
                            for (let i = 0; i <diff; i++) {
   
                                if(unfinishedList.length>0){
   
                                    unfinishedList.splice(0,1);
                                }
                            }
                        }
                    }else {
   //上传完成
                        if(timer!=null){
   
                            clearInterval(timer);
                            timer=null;
                        }
                    }
            },500);
        }
        if(timerTable==null){
   
            timerTable=setInterval(function (d) {
   
                keepTime++;//计时
                if(unfinishedList.length==0&&beingList.length==0){
   
                    reloadTable(option,true);
                    clearInterval(timerTable);
                    timerTable=null;
                }else {
   
                    reloadTable(option,false);
                }
            },1000);
        }
    }


    /*
    文件夹拖拽上传
    在 drop 事件中获取 e.dataTransfer.items ,是一个 DataTransferItemList 对象,遍历得到 DataTransferItem 对象
    用 webkitGetAsEntry 方法得到 FileSystemEntry 对象
    根据 isFile 属性判断 entry 是文件还是文件夹。是文件的话,用 file 方法获取 File 对象;是文件夹的话,递归地用 reader 读取包含的文件
    原文链接:https://blog.csdn.net/tangran0526/article/details/104156857
    * */
    function scanFiles(e,option) {
   
        e.preventDefault();
        //var files=[];
        var item=e.dataTransfer.items;//获取DataTransferItemList 对象
        if(item&&item.length>0){
   
            var serialNumber=uuid();//同一上传批次序列号下的同名文件夹不重复添加
            for (var it of item) {
   
                var entry=it.webkitGetAsEntry();//获取 FileSystemEntry 对象
                fileReader(entry,function (file, path) {
   
                    uploadServer(file,uuid(),"1",path,option,serialNumber);
                });
            }
        }
    }


    function fileReader(entry,succ) {
   
        if (entry.isFile) {
   
            entry.file(file => {
   
                // 这里的 file.webkitRelativePath 都是 "" ,不是我们想要的.
                // entry.fullPath 是前面带斜杠的,要把斜杠去掉的
                let path = entry.fullPath.substring(1);
                succ(file,path);
            });
        } else {
   
             getEntryDirectoryFiles(entry).then(data=>{
   
                 data.forEach(_this=>{
   fileReader(_this,succ);});
             });

        }
    }

    // 获取文件夹所有子集
     function getEntryDirectoryFiles(entry) {
   
        const reader = entry.createReader()
        // 一次最多只能读100,防止出现文件夹内文件个数过多,加一个变量收集最新的结果
        let res = []
         return read();
        async function read() {
   
            const files = await new Promise((resolve, reject) =>
                reader.readEntries((entries) => {
   
                    // 只上传一层文件,过滤文件夹中包含的文件夹
                    //const fileEntries = entries.filter((entry) => entry.isFile)
                    const filesPromise = entries.map((e) => new Promise((resolve) =>resolve(e)))
                    Promise.all(filesPromise).then(resolve)
                }, reject)
            )
            // 保存当前读取文件
            res = [...res, ...files]
            // chrome浏览器一次读取最多获取100个文件,多于100个需要再次读取
            if (files.length < 100) {
   
                return res
            }
            return read()
        }
    }

    async function read(entry,res) {
   
        const reader = entry.createReader();
        for (let i = 0; i < 3; i++) {
   
        await new Promise((resolve, reject) =>{
   
            debugger;
                reader.readEntries((entries) => {
   
                    debugger;
                    console.log(entries.length);
                    // 只上传一层文件,过滤文件夹中包含的文件夹
                })
            }
        )
        }
    }


    function renderDrop(option) {
   
        $("#"+option.dropId).click(function (e) {
LayUI的`layui.upload`是用于文件上传的功能模块,你可以通过以下几个步骤在HTML和JavaScript中实现点击事件驱动的文件上传: 1. 引入必要的CSS和JS文件: ```html <link rel="stylesheet" href="https://layui.layui.com/layui.css"> <script src="https://layui.layui.com/layui.js"></script> ``` 2. 创建一个上传按钮并设置点击事件: ```html <button id="uploadBtn" lay-event="upload">点击上传文件</button> <input type="file" id="fileInput" style="display:none;"> <!-- 隐藏的文件选择输入框 --> <!-- 使用layui.upload配置 --> <script> layui.use(['layer', 'upload'], function () { var layer = layui.layer; var upload = layui.upload; // 上传配置 var opt = { elem: '#fileInput', // 指定上传区域 url: '/api/upload', // 上传服务器接口 URL headers: {/* 添加自定义HTTP头部 */} }; // 点击事件 $('#uploadBtn').on('click', function() { upload.render(opt); // 初始化并开始监听文件选择 }); // 文件上传完成后的回调 upload.on('success', function(data, file) { layer.msg('文件上传成功,文件ID:' + data.id, {time: 1000}); // 提示用户上传结果 // 数据处理,例如保存到数据库或页面展示 saveToFileID(data.id); // 自定义函数保存文件ID }); // 错误处理 upload.on('error', function(data, file) { layer.msg('文件上传出错:' + data.message, {time: 2000}); }); }); ``` 在这个例子中,`layEvent='upload'`绑定了点击事件,当用户点击按钮时会触发`upload`事件。`upload.render(opt)`初始化文件上传,`opt.url`是你服务器端的接收文件的URL。`upload.on('success')`和`upload.on('error')`分别用于处理上传成功的回调和错误的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值