js上传文件夹(js获取文件夹下所有文件)
文章目录介绍功能环境需要在服务下运行!!!步骤引入polyfill.js代码如下。(不需要vue环境,这里只是习惯用vue)效果图介绍项目中有需要实现拖拽文件夹上传功能,虽然可以通过设置input 的webkitdirectory属性实现。但是这种方式的兼容性却不好。如图:webkitdirectory兼容性博主找遍全网都没有找到合适的解决方案,直到发现下面一篇文章directory-upload
·
介绍
项目中有需要实现拖拽文件夹上传功能,虽然可以通过设置input 的webkitdirectory属性实现。但是这种方式的兼容性却不好。如图:
webkitdirectory兼容性
博主找遍全网都没有找到合适的解决方案,直到在网上找到一些例子
but这个例子有个问题:就是多个子文件夹时,路径数据是错误的。
由此本文修改后的代码,请以我为准。
思路
- 获取文件夹中所有文件
- 上传文件。(文件中需要包含对应文件的相对路径!!!)
- 根据文件的路径需要后端在服务器创建对应文件夹,然后放置对应文件。(将文件存放至对应的文件夹)
功能
- 拖拽文件夹上传,主要难点是在获取文件夹各子文件的数据和路径。
- 支持多个文件,多个文件夹,多级文件夹上传。
兼容性: Chrome 25+
环境
步骤
引入polyfill.js
代码如下。(不需要vue环境,这里只是习惯用vue)
<template>
<div>
<div id="dropDiv">请将拖拽文件/文件夹至此</div>
<h3>
文件列表,更多请见console
</h3>
<div id="outPut"></div>
</div>
</template>
<script>
import "./polyfill.js";
export default {
name: "directory-upload-example",
data() {
return {
};
},
mounted() {
let dz = document.getElementById("dropDiv");
dz.ondragover = function (ev) {
//阻止浏览器默认打开文件夹的操作
ev.preventDefault();
//拖入文件后边框颜色变蓝
this.style.borderColor = "#6ba1d0b3";
this.style.borderWidth = "2px";
this.style.borderStyle = "dashed";
this.style.backgroundColor = "rgba(133, 192, 241, 0.3)";
};
dz.ondragleave = function () {
//文件脱出热区后恢复边框颜色
this.style.borderColor = "#cccccc";
this.style.borderWidth = "1px";
this.style.borderStyle = "solid";
this.style.backgroundColor = "#fff";
};
dz.addEventListener("drop", function (e) {
//拖动操作后的热区样式
dz.style.borderColor = "#cccccc";
dz.style.borderWidth = "1px";
dz.style.borderStyle = "solid";
dz.style.backgroundColor = "#fff";
e.stopPropagation();
e.preventDefault();
let okFiles = []; //递归文件夹后 保存所有file的Array
let step = 0; //当前遍历次数
let folderNum = 1; //需要遍历的次数 有一个子文件夹就需要遍历一次
const iterateFilesAndDirs = async function (filesAndDirs, path) { // 遍历目录的文件夹和文件
const folderArr = filesAndDirs.filter((item) => { //当前目录的子文件夹
return item._items && item._items.isDirectory;
});
folderNum += folderArr.length; //当前目录下还需遍历多少次 有多少个子文件夹就需要遍历几次
step += 1; //遍历次数
for (let i = 0; i < filesAndDirs.length; i++) {
if (typeof filesAndDirs[i].getFilesAndDirectories === "function") {//文件夹 遍历
let dpath = filesAndDirs[i].path;
// 递归遍历各级目录
filesAndDirs[i]
.getFilesAndDirectories()
.then(function (subFilesAndDirs) {
// 遍历子目录的文件夹和文件
iterateFilesAndDirs(subFilesAndDirs, dpath);
});
} else {
//如为文件则存储在okFiles 里面
let file = filesAndDirs[i];
file.fullPath = path; //组装该文件的相对路径
okFiles.push(file);
}
}
if (step >= folderNum) { //计算是否遍历完毕 即 当前共遍历了多少次 == 总共需要遍历的次数(文件夹数量) 则遍历完毕
//确定是最后一次遍历后执行上传操作
console.log(okFiles); //得到此次上传的所有文件 不包含空文件夹
//上传okFiles 的文件
let formData = new FormData();
let fileStr = "";
for(let file of okFiles){
formData.append("file", file);
fileStr+=`<span>名称:${file.name} 路径:${file.fullPath}</span><br/>`
}
document.getElementById("outPut").innerHTML=fileStr;
// //上传文件
// this.$axios
// .post("url", formData)
// .then((res) => {
// /*
// *
// *
// */
// })
// .catch((error) => {
// /*
// *
// *
// */
// });
}
};
// 遍历选定的文件夹 // 支持文件 文件夹 多个文件夹
if ("getFilesAndDirectories" in e.dataTransfer) {
e.dataTransfer.getFilesAndDirectories().then(function (filesAndDirs) {
iterateFilesAndDirs(filesAndDirs, "/");
});
}
});
},
};
</script>
<style scoped>
#dropDiv {
width: 100%;
border: 1px solid #cccccc;
margin-top: 20px;
padding: 80px 20px;
text-align: center;
color: #cccccc;
}
</style>
效果图
- 文件夹内容
- 上传
- 效果
更多推荐
已为社区贡献4条内容
所有评论(0)